JavaScript——驰骋网页的脚本执行者(4)

六、数组

1.数组的介绍

ECMAScript数组是有序列表,是存放多个值的集合,属于引用数据类型。它的特性有:

每一项都可以保存任何类型的数据;

数组的大小是可以动态调整的;

可以访问或改变数组的length属性(数组也是一种对象,length是表示数组长度的属性,length表示数组中数组项的个数):通过设置length的值在数组末尾移除数组项,或者向数组中添加新的数组项。

 

2.数组的创建

使用Array构造函数创建数组,如:

var arr = new Array();

var arr = new Array(20); //预先指定数组的长度

var arr = new Array("terry","larry","boss"); //传入参数作为数组项

Array继承Object通过Array构造函数构建出来的对象可以调用Array原型中的方法,还可以调用Object原型中的方法arr ->Array.prototype->Object.prototype)。

 

使用数组字面量创建数组,由一对包含数组项的方括号表示,多个数组项之间用逗号分隔,如:

var arr = ["terry","larry","boss"]; //数组的初始化

var arr = [] //空数组

 

3.数组的检测

对于一个网页或者一个全局作用域而言,使用instanceof操作符即可判断某个值是否是数组。如果网页中包含多个框架,这样就存在多个不同的全局执行环境,从而存在多个不同版本的Array构造函数,这样就会判断不准确。为解决这个问题,ECMAScript5新增了Array.isArray()方法进行判断,如:

var arr = [];

typeOf(arr); //object

arr instanceof Array //true,在同一个全局作用域下可以这么判断

Array.isArray(arr); //true,判断arr是否是数组类型

 

4.数组的访问

通过“数组变量名[索引]”访问数组,如果索引小于数组的长度,返回对应项的值;如果索引大于数组的长度,数组自动增加到该索引值加1的长度(因为数组索引从0开始)(数组中最多可以包含4 294 967 295个数组项),且值为undefined,如:

var arr = ["terry","larry","boss"];
arr[0] ;                        //访问数组中第一个元素,返回值为terry
arr[3] ="jacky";                //添加元素,数组程度变为4
(["terry","larry","boss","jacky"])
arr[9] ;                        //访问数组中第十个元素,返回值为undefined

 

可以使用循环语句遍历数组,如:

for(var i = 0; i<arr.length; i++){
    var val = arr[i]
    console.log(val);
}

for(var key in arr){
    var val = arr[key]
}

 

5.通过栈和队列操作操作数组项

(先进后出)操作:

push()可接受任意类型的参数,将它们逐个添加到数组的末尾,并返回数组的长度,参数为要入栈的元素,返回值为数组长度

pop()从数组的末尾移除最后一项,减少数组的length值,返回移除的项,无参数,返回值为出栈的元素

队列(先进先出)操作:

shift()移除数组中的第一个项并且返回该项,同时将数组的长度减一,无参数,返回值为出队的元素

unshift()在数组的前端添加任意个项,并返回新数组的长度,参数为要插队的元素,返回值为插队后队列的长度

 

6.数组的截取

concat():数组拼接先创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,返副本,不改变原数组。

slice():数组切割。接收的参数为(start,end(可选))只接收start返回start指定位置开始到当前数组末尾的所有项接收startend返回startend之间的项,但不包含end位置的项不改变原数组

splice():数组更改。具体使用如下:

删除:指定两个参数(删除的起始位置,要删除的项数)

插入:指定三个参数(起始位置,0,要插入的任意数量的项)

替换:指定三个参数(起始位置,要替换的项,要插入的任意数量的项)

 

7.数组的排序

reverse():可以反转数组项的顺序

sort():默认排序会调用每个数组项的toString()方法,然后按照字符序列排序;

自定义排序可以接受一个比较函数作为参数(sort(comparator)),比较函数有两个参数(compare(a,b)),降序排序情况是,如果第一个参数位于第二个参数之后(小于第二个参数),返回正数(调换),如果第一个参数位于第二个参数之前(大于第二个参数),返回负数(保持),如下:

var arr = [3,12,29,8,32,4];
arr.sort(function(a,b){
    if(a<b){
        return 1;
    } else {
        return -1;
    }
});
console.log(arr);    //[ 32, 29, 12, 8, 4, 3 ]

 

对象数组的排序,需要灵活运用作为sort参数的比较函数,例如:

有一个学生的对象数组,要求实现按照id/name/age/grade来升序或者降序排列,方法的调用形式为students.sort(handler()),那么该如何设计handler()方法。

var students = [{
        id:1,
        name:"terry",
        age:12,
        grade:89
    },{
        id:3,
        name:"larry",
        age:9,
        grade:92
    },{
        id:2,
        name:"tom",
        age:13,
        grade:99
    },{
        id:4,
        name:"jacky",
        age:11,
        grade:85
    }]

解决方法之一:

var prop = "grade";
students.sort(handler(prop));
console.log(students);

function handler(key){
//返回比较器函数
    return function(a,b){
        if(a[key] > b[key]){
            return 1;
        } else {
            return -1;
        }
    }
}

 

8.数组的迭代

every():对数组中的每一项运行给定的函数,如果该函数对每一项都返回true,则该函数的执行结果返回结果为true,如:

var arr = [11,5,23,7,4,1,9,1];
var result = arr.every(function(item,index,arr){
        return item >2;
});
console.log(result);        //false,数组中存在小于2的项

 

some():对数组中的每一运行给定的函数,如果该函数一项返回true,该函数执行结果返回true,如:

var arr = [11,5,23,7,4,1,9,1];
var result = arr.some(function(item,index,arr){
    return item >2;
});
console.log(result);        //true,数组中存在大于2的项

 

filter():对数组中的每一运行给定的函数,会返回满足该函数的项组成的数组,如:

var arr = [11,5,23,7,4,1,9,1];
var result = arr.filter(function(item,index,arr){
    return item >2;
});
console.log(result);        //[11, 5, 23, 7, 4, 9],数组中的这些项大于2

 

map():对数组中的每一运行给定的函数返回每次调用函数的结果组成的数组,且返回值可以为任意类型(常用于抽取对象数组中的特定属性值),如:

var arr = [11,5,23,7,4,1,9,1];
var result = arr.map(function(item,index,arr){
    return item * 2;
});
console.log(result);        //[22, 10, 46, 14, 8, 2, 18, 2],数组中所有项*2后的结果组成的数组
var students = [{
        id:4,
        name:"terry",
        age:12,
        grade:92
},{
        id:1,
        name:"tom",
        age:11,
        grade:89
},{
        id:3,
        name:"vicky",
        age:15,
        grade:95
},{
        id:2,
        name:"larry",
        age:19,
        grade:82
}];
var result = students.map(function(item){
    return item.age;
});
console.log(result);        //[12, 11, 15, 19],对象数组中的age属性值做成的数组

forEach():对数组中的每一运行给定的函数没有返回值,常用来遍历元素,如:

var arr = [11,5,23,7,4,1,9,1];
var result = arr.forEach(function(item,index,arr){
    console.log(item);
});
//11,5,23,7,4,1,9,1,得到数组的遍历值(也可以操作index和arr,比如输出它们)

 

9.数组的序列化

toString():在默认情况下会以逗号分隔字符串的形式返回数组项,如:

var arr = ["terry","larry","boss"];

arr.toString(); //terry,larry,boss

join():使用指定的字符串用来分隔数组字符串,如:

var arr = ["terry","larry","boss"];

arr.join("||"); //terry||larry||boss

JSON.stringify():将数组转换为JSON字符串,如:

JSON.stringify(["tom","larry",1,45,33,24,5]);

'["tom","larry",1,45,33,24,5]'

 

10.部分数组方法重构

1)模拟push(),重构为myPush()代码。

Array.prototype.myPush = function(){
    var len = this.length;    //2
    for(var key in arguments){
        var item = arguments[key];
        this[len+(+key)] = item;    //将字符串形式的key转成number
    }
    return this.length;
}

var arr = [3,12,29,8,32,4];
var result = arr.myPush("terry","larry","tom")
console.log(result,arr);    //9 [3,12,29,8,32,4,"terry","larry","tom"]

var arr2 = [3,12,29,8,32,4];
var result2 = arr2.push("terry","larry","tom");
console.log(result2,arr2);    //9 [3,12,29,8,32,4,"terry","larry","tom"]

 

2)模拟pop(),重构为myPop()代码。

Array.prototype.myPop = function(){
        var del = this[this.length - 1];
        this.length -= 1;
        return del;
}

var arr = [3,12,29,8,32,4];
var result = arr.myPop();
console.log(result,arr);    //4 [3,12,29,8,32]

var arr2 = [3,12,29,8,32,4];
var result2 = arr2.pop();
console.log(result2,arr2);    //4 [3,12,29,8,32]

 

3)模拟shift(),重构为myShift()代码。

Array.prototype.myShift = function(){
        var del = this[0];
        this.splice(0,1);
        return del;
}

var arr = [3,12,29,8,32,4];
var result = arr.myShift();
console.log(result,arr);    //3 [12,29,8,32,4]

var arr2 = [3,12,29,8,32,4];
var result2 = arr2.shift();
console.log(result2,arr2);    //3 [12,29,8,32,4]

 

4)模拟unshift(),重构为myUnshift()代码。

Array.prototype.myUnshift = function(){
        for(var key in arguments){
                this.splice(key,0,arguments[key]);
        }
        return this.length;
}

var arr = [3,12,29,8,32,4];
var result = arr.myUnshift("terry","larry","tom")
console.log(result,arr);    //9 ["terry","larry","tom",3,12,29,8,32,4]

var arr2 = [3,12,29,8,32,4];
var result2 = arr2.unshift("terry","larry","tom");
console.log(result2,arr2);    //9 ["terry","larry","tom",3,12,29,8,32,4]

 

5)模仿every(),重构myEvery()代码。

Array.prototype.myEvery = function(handler){
    var flag = true;
    for(var i=0;i<this.length;i++){
        var item = this[i];
        var result = handler(item,i,this);    //回调函数,将参数传给内置函数进行条件判断
        if(result){
            continue;
        } else {
            flag = false;    //存在不满足条件的数组项
            break;
        }
    }
    return flag;
}

var arr = [1,3,5,6,7];
var result = arr.myEvery(function(item,index,arr){
    console.log("myEvery执行1次");
    return item % 2 !== 0;
});
console.log(result);        //false,6不满足判断条件

 

(6)模拟filter(),重构myFilter()代码。

Array.prototype.myFilter = function(handler){
        var array = [];
        // for(var i in this){
        for(var i=0;i<this.length;i++){
            console.log(i,'---');
            var item = this[i];
            var result = handler(item);
            if(result){
                array[array.length] = item;
            }
        }
        return array;
}

var arr = [1,2,3,5,7,12];
var result = arr.myFilter(function(item){
        return item%2 == 0;
})
console.log(result);        //[2,12]

 

7)模拟forEach(),重构myForEach()代码。

Array.prototype.myForEach = function(callback){
    for(var i=0;i<this.length;i++){
        callback(this[i],i,this);    //回调函数,handler通过callback传值得到三个参数,相当于原生every中内置函数的三个参数
    }
}

var arr = ["terry","larry","tom"];
var handler = function(item,index,arr){
    console.log(item,index,arr);
}
arr.myForEach(handler);
//terry,0,["terry","larry","tom"]
//larry,1,["terry","larry","tom"]
//tom,2,["terry","larry","tom"]
posted @ 2019-08-25 17:23  我的祈愿  阅读(161)  评论(0编辑  收藏  举报