JavaScript/ES6中的数组

数组的特性、操作、使用:数组可以直接赋予数组字面量,也可以用Array构造器生成,也可以利用数组的静态方法或实例方法生成一个数组;

1,ES6新特性:新加两个静态方法Array.from(arr, ?mapFn, ?thisArg)、 Array.of(...items); 新加几个实例方法: Array.prototype.find(conditionFn, ?thisArg)、Array.prototype.findIndex(conditionFn, ?thisArg)、Array.prototype.includes(item,?fromIndex)、Array.prototype.fill(value, ?startIndex, ?endIndex)、Array.prototype.copyWithin(targetIndex, toStart, ?toEnd)、Array.prototype.flat(level)、Array.prototype.flatMap(mapFn, ?thisArg)、Array.prototype.entries()、Array.prototype.keys()、Array.prototype.values();新增类型构造器 ArrayBuffer、TypedArray;

以下用例子说明各特性的使用:

//数组的创建: -------------------------
var arr1 = new Array(2); //创建一个拥有两个空元素的数组;arr1.length === 2; 
                        //因为空元素,访问时,arr1[0] === undefined;
var arr2 = new Array(2, 4);
var arr3 = new Array('4');
console.log(arr1, arr2, arr3);
//[empty × 2]   [2, 4]     ["4"]
console.log(arr1[0], arr1.length);
//undefined    2
//arr2 和 arr3可以直接赋予数组字面量,arr2 = [2, 4]; arr3 = ['2'];
//arr1 可以这样:arr1 = []; arr1.length = 2;或者直接arr1 = [,,];
//需要两个逗号,因为最后一个空格会被忽略,就像[1,2,]是[1,2];
arr1 = [,,];
arr2 = [2, 4];
arr3 = ['4'];
console.log(arr1, arr2, arr3);
//[empty × 2]   [2, 4]   ["4"]
//访问数组元素:-----------------------------
//includes(item, ?fromIndex); 判断元素item是否在数组中,formIndex可选,
//表示从哪个下表开始检索;默认为0; 返回值是bool值 true or false
//includes可以判断NaN
console.log(arr2.includes(2, 0));
//true
console.log([NaN, NaN, 2].includes(NaN)); 
// true
//find(conditionFn, ?thisArg); 查找符合条件的元素,找到第一个后返回;若找不到,返回undefined;
//conditionFn条件函数,条件函数中的this会指向thisArg;
//若thisArg没有给,那么条件函数的this遵从js的this的规则当然如果条件函数是箭头函数,
//则thisArg不起作用
console.log(
    arr3.find(item => {
        if(typeof item === 'string') 
            return true;
        return false;
    })
); 
//'4'
//findIndex(coditionFn, ?thisArg);跟find类似,只是find返回符合条件的元素,
//findIndex返回元素的下标;若找不到,返回-1;
console.log(
    arr3.findIndex(item => {
        if(typeof item === 'string') 
            return true;
        return false;
    })
); 
//0
//entries(),返回一个迭代器,通过迭代器可以遍历数组的键值对数;
//当遇到空元素时,跟访问空元素一样, value是undefined
var iterator1 = arr1.entries();
console.log(
    iterator1.next()
); 
//{value:[0, undefined], done: false}
var iterator2 = arr2.entries();
console.log(
    iterator2.next()
); 
//{value:[0, 2], done: false}
//keys, 返回一个迭代器,通过迭代器可以遍历数组的键名;
var iterator1 = arr1.keys();
console.log(
    iterator1.next()
); 
//{value: 0, done: false}
var iterator2 = arr2.keys();
console.log(
    iterator2.next()
); 
//{value:0, done: false}
//values,同上;
//注意,跟Object.entries(obj),Object.keys(obj),Object.values(obj)不一样:-------------
//Object的这3个方法返回的是数组;
//另外Object.entries(arr1),不同于arr1.entries(), 它返回的是个长度为0的空数组,
//空元素无法遍历。
//以参数为模板,创建一个新的数组;基本都是浅拷贝shadow copy; 若有回调函数像mapFn,---------
//一般回调有这几个参数:item, index, arr
//Array.from(Array | likeArray | iterableObj, ?mapFn, ?thisArg);
//模板可以是个数组[1,2, [2,3]],
//也可以是个至少拥有length属性的类数组{length: 2},
//也可以是个不是数组的可迭代对象或字面量'str';
var arr = [1, 6, [2, [5, 10]], 'str'];
var fromArr =  Array.from(arr);//shadow copy
console.log(fromArr);
//[1, 6, [2, [5, 10]], 'str']
console.log(arr === fromArr); //shadow copy
//false
fromArr[2][0]= 8;
console.log(arr[2][0]);
//8
console.log(
    Array.from({length: 2})
); //类数组必须有length属性,其他属性可选,像这样:{0: 'test', 1: 23, length: 2}
//[undefined, undefined]
console.log(
    Array.from('str')
);
//['s', 't', 'r']
//Array.of(...items);将所有参数合并为一个数组;参数可以是任意类型的组合;
//注:empty只是用来表示空元素,表示空,但它不存在于JS环境中
console.log(
    Array.of('str', 1,  [3,,3], {a: 'a'}, null, true)
);
//['str', 1,  [3, empty, 3], {a: 'a'}, null, true]
//flat(?level);平铺多维数组,返回一个平铺后的新数组;不改变原数组;level默认值是1;
//level若为0,表示复制原数组但不平铺;
//关键字Infinity表示正无穷,是个Number类型;若level为Infinity,表示平铺所有嵌套维数。
console.log(
    arr.flat(), arr.flat(0), arr.flat(Infinity)
);
//[1, 6, 8, [5, 10], 'str']   [1, 6, [8, [5, 10]], 'str']   [1, 6, 8, 5, 10, 'str']
//flatMap(mapFn, ?thisArg);先利用mapFn进行map,再以level为1进行平铺,
//再把结果组成一个新数组返回;thisArg指定mapFn的this
console.log(
    arr.flatMap(item => {
        if(typeof item === 'number')
            return item + 3;
        return item;
    })
);
//[4, 9, 11, [5, 10], 'str']
//修改原数组: ----------------------------------------------
//fill(value, ?start, ?end);用指定数据value填充数组, start表示开始位置(include),
//不传表示从0开始;
//end表示结束位置(excludes),不传表示数组的length;不包括end的那个元素;
var arrTobeChanged = [2, 4, 6, 8, 10];
console.log(
    Array.from(arrTobeChanged).fill(0),
    Array.from(arrTobeChanged).fill(0, 3, 4),
    Array.from(arrTobeChanged).fill(0, 3)
);
//[0, 0, 0, 0, 0]   [2, 4, 6, 0, 10]   [2, 4, 6, 0, 0]
//copyWithin(targetIndex, startIndex, ?endIndex);用数组内的某段元素覆盖指定下标起的一段元素;
//targetIndex表示目标段,被覆盖的开始下标,startIndex表示复制开始的下标(includes),
//endIndex表示复制结束的下标(excludes);
//最后返回被修改的原数组;
//若没有传参数,则什么都没做;
console.log(
    //将下标 3开始到下标 4结束(不包括下标4)的这段元素覆盖从index 0开始的一段元素
    arrTobeChanged.slice().copyWithin(0, 3, 4), 
    //将下标 3开始到下标 5结束(不包括下标5)的这段元素覆盖从index 0开始的一段元素
    arrTobeChanged.slice().copyWithin(0, 3, 5),
    //将下标 3开始到下标 length结束(不包括下标 length)的这段元素覆盖从index 0开始的一段元素
    arrTobeChanged.slice().copyWithin(0, 3),
    arrTobeChanged.slice().copyWithin(), //什么都没做
);
//[8, 4, 6, 8, 10]   [8, 10, 8, 8, 10]   [8, 10, 6, 8, 10]  [2, 4, 6, 8, 10]
//ArrayBuffer;创建数组缓冲区,数组缓冲区是内存的一段地址;不同于普通数组,------------------
//ArrayBuffer一旦创建,大小不能修改,且需要通过视图对其操作;数组缓冲区是个固定的状态 
//只能通过new ArrayBuffer(length) 创建数组缓冲区;
var arrBf = new ArrayBuffer(4);
console.log(arrBf.length, arrBf.byteLength); //ArrayBuffer实例没有length属性,但有byteLength;
//undefined 4
//创建视图,操作缓冲区 new DatView(arrayBuffer, ?offset, ?length);
//DataView是用来操作内存的接口:
var dataView = new DataView(arrBf);
//通过DatView的接口操作缓存: setIntX(offset, value);X表示具体的数字:8,16,32等;
//还有setFloatX(offset, value);响应有各种get方法;
//offset表示偏移量,字节数;单位是Byte;
dataView.setInt8(0, 8);
console.log(dataView.getInt8(0));//获取缓冲区的第一字节的数值;
//8
//TypedArray; 类型化数组;TypedArray构造函数并没有暴露,所以不能直接使用TypeArray;
//有以下具体类型数组继承了TypedArray:
//Int8Array,Uint8Array, Uint8ClampedArray,Int16Array,Uint16Array, 
//Int32Array, Uint32Array,Float32Array, Float64Array等
//这些类型可以被用作数组缓冲区的视图,可以操作数组缓冲,类似于DataView;
//而DataView是通用的数组缓冲区视图,DataView实现具体类型数组的接口
//TypedArray实例的大小也是固定的,不可修改它的length;
var int8Array = new Int8Array(arrBf);
console.log(int8Array[0]);
//8
//数组的很多方法可以通过call或apply用于非数组的调用,如类数组-----------------

2, 数组的其他特性、操作等:Array.isArray(obj)、Array.prototype.pop()、Array.prototype.shift()、Array.prototype.push(...items)、Array.prototype.unshift(...items)、Array.prototype.concat(...items)、Array.prototype.slice(?fromIndex, ?endIndex)、Array.prototype.splice(index, ?length, ?...items)、Array.prototype.reverse()、Array.prototype.reduce(fn, ?initialVal)、Array.prototype.reduceRight(fn,?initialVal)、Array.prototype.sort(?compareFn)、Array.prototype.join(?seperator)、Array.prototype.indexOf(searchValue, ?fromIndex)、Array.prototype.lastIndexOf(searchValue, ?fromIndex)、Array.prototype.filter(filterFn, ?thisArg)、Array.prototype.every(fn, ?thisArg)、Array.prototype.some(fn, ?thisArg)、Array.prototype.forEach(fn, ?thisArg)、Array.prototype.map(conditionFn, ?thisArg)

var arr = [6, 8, 9];
//Array.isArray(obj);用于判断目标对象是否是数组;-------------------
console.log(Array.isArray(arr));
//true
console.log(Array.isArray({}));
//false
//遍历数组:------------------------
//concat,slice,join,reduceRight,reduce
//Array.prototype.concat(...arrs);是将多个数组或其他类型数据合并成一个新数组;
console.log(
    arr.concat([9, 10], 'str', {0: 4, length: 2})
);
//[6, 8, 9, 9, 10, 'str', {0:4, length: 2}]
//Array.prototype.slice(?fromIndex, ?endIndex);从当前数组抽取一段元素组成一个新数组;
//fromIndex表示从哪个下标开始复制(includes),endIndex表示在哪个下标前结束(excludes,不包括结束下标的元素);
//fromIndex和endIndex都没给值,表示复制整个当前数组的元素;
//endIndex可以是负数,表示倒数第几个结束,如-1,表示在倒数第一个结束(不包括);
console.log(
    arr.slice(),
    arr.slice(0, 2),
    arr.slice(0, -1)
);
//[6, 8, 9]   [6, 8]  [6, 8]
//Array.prototype.join(seperate);用于将数组元素用指定字符隔开合并成一个字符串,若没有给隔开字符,默认是','
console.log(
    arr.join('&'),
    arr.join()
);
// '6&8&9'   '6,8,9'
//Array.prototype.reduce(fn, ?initalValue);用于将数组元素累加,并输出最后的结果;
//initialValue是初始值,在第一次调用fn时,给到fn的第二个参数;
//当没有给初始值initialValue时,第一次调用回调时total的值是arr的第一个元素;
console.log(
    arr.reduce((total, item, index, arr) => item + total),
    arr.reduce((total, item, index, arr) => item + total, 5)
);
//23    28
//Array.prototype.reduceRight(fn, ?initalValue);作用跟reduce一样,只是reduceRight是从数组的最后一个开始遍历;
//Array.prototype.indexOf(value, ?fromIndex);用于检索一个指定元素在当前数组的位置;
//fromIndex表示从哪个下标开始并往后检索;默认为 0;可为负数, 如-2表示从倒数第二个元素开始并往后检索;
console.log(
    arr.indexOf(8),
    arr.indexOf(8, 2),
    arr.indexOf(8, -1),
    arr.indexOf(8, -2)
);
//1  -1  -1  1
//Array.prototype.lastIndexOf(value, ?fromIndex);跟indexOf类似;
//只是lastIndexOf是从数组的最后开始并往前检索,跟indexOf的检索方向不同;
console.log(
    arr.lastIndexOf(8),
    arr.lastIndexOf(8, 2),
    arr.lastIndexOf(8, -1),
    arr.lastIndexOf(8, -3)
);
// 1  1  1 -1
//Array.prototype.filter(filterFn, ?thisArg);用于过滤数组;
//符合条件的元素return true,不和条件的return false;
//最后得到一个新数组,是符合条件的元素的集合:
console.log(
    arr.filter(item => item >8),
    arr
);
//[9]    [6, 8, 9]
//Array.prototype.every(conditionFn, ?thisArg);用于判断是否每个元素都符合条件;
//都符合的最终返回true,若有任意个不符合,最终返回false
console.log(
    arr.every(item => item > 5),
    arr.every(item => item > 7),
    arr.every(item => true)
);
//true  false   true
//Array.prototype.some(conditionFn, ?thisArg);用于判断是否存在任意个元素符合条件:
//若存在, 返回true;
console.log(
    arr.some(item => item > 10),
    arr.some(item => item > 7),
    arr.every(item => false)
);
//false  true  false
//Array.prototype.forEach(fn, ?thisArg);遍历整个数组元素;
arr.forEach((item, index, arr) => console.log(item, index));
//6 0
//8 1
//9 2
//Array.prototype.map(conditionFn, ?thisArg);用于将元素进行映射;返回map之后的新数组;
console.log(
    arr.map(item => item + 2),
    arr
);
//[8, 10, 11]   [6, 8, 9]
//修改数组:------------------------------------
//pop,push,shift,unshift,reverse,splice,sort,
//Array.prototype.pop();用于删除数组的最后的一个元素,并返回被删除的那个元素;
//也可用于类数组:Array.prototype.pop.call({1: 'test', length: 2})
console.log(
    arr.pop(),
    arr
);
//9  [6,8]
var obj = {1: 'test', length: 2};
console.log(
    Array.prototype.pop.call(obj),
    obj
);
//'test'   {length: 1}
//Array.prototype.shift();用于删除数组的第一个元素,并返回被删除的那个元素;
console.log(
    arr.shift(),
    arr
);
//6   [8]
//Array.prototype.push(...items);用于在数组末尾添任意个任意类型的元素;并返回新的 length;
console.log(
    arr.push(2, 'str', [3, 5], {a: 'test'}),
    arr
);
//5   [8, 2, 'str', [3, 5], {a: 'test'}]
//Array.prototype.unshift(...items);用于在数组开头添加任意个任意类型的元素,并返回新的 length
console.log(
    arr.unshift(3, 7),
    arr
);
//7  [3, 7, 8, 2, 'str', [3, 5], {a: 'test'}]
//Array.prototype.splice(index, ?length, ?...items);用于从指定下边开始删除指定个数的元素,
//并从index开始添加任意个任意类型的元素; 若length不传值,则表示删除从index开始到最后的元素;
//返回被删除的元素的集合;splice的操作会影响原数组;
var shad1 = arr.slice();
var shad2 = arr.slice();
var shad3 = arr.slice();
var shad4 = arr.slice();
console.log(
    shad1.splice(4), //从下标为 4 开始删除
    shad2.splice(4, 1), //从下标为4开始删除,只删除一个元素
    shad3.splice(4, 2, 90), //从下标为 4开始删除, 删除两个元素,并在下标为4的位置添加一个元素
    shad4.splice(4, 2, 90, 80, 70)//同上,但添加的是3个元素
);
//['str', [3, 5], {a: 'test'}]    ['str']    ['str', [3, 5]]    ['str', [3, 5]]
console.log(
    shad1, shad2, shad3, shad4
);
//[3, 7, 8, 2]   [3, 7, 8, 2, [3, 5], {a: 'test'}] 
//[3, 7, 8, 2, 90, {a: 'test'}]   [3, 7, 8, 2, 90, 80, 70, {a: 'test'}]
//Array.prototype.reverse():用于反转原数组,并返回原数组;reverse改变了原数组;
console.log(
    arr.reverse(),
    arr
);
//[{a: 'test'}, 70, 80, 90, 2, 8, 7, 3]   [{a: 'test'}, 70, 80, 90, 2, 8, 7, 3]
//Array.prototype.sort(?compareFn);用于排序原数组;compareFn可选,规定排序规则(按从小或按从大),默认按从小排序;
var arrSort = [4, 3, 0, 2, 8];
console.log(
    arrSort.sort()
);
//[0, 2, 3, 4, 8]
console.log(
    arrSort.sort((a, b) => a-b) //跟默认的一样从小到大排序
);
//[0, 2, 3, 4, 8]
console.log(
    arrSort.sort((a, b) => b-a) //从大到小排序
);
//[8, 4, 3, 2, 0]

3,参考文档:

ES6 Array

数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值