ES6新增API(Array篇(二))
新增的原型方法
- Array.prototype.copyWithin
函数类型:
/** * @author: forceddd * @desc:将数组中的,从start位置开始至end位置(不包含end处的元素)结束的元素,进行浅复制,并从target处开始覆盖该数组。最后将修改后的数组返回 * @param {number} target 复制到数组的起始覆盖位置,默认值为0 * @param {number} start 开始复制元素的位置,默认值为0 * @param {number|undefined} end 结束复制元素的位置,默认值为数组长度 * @return {any[]} 改变之后的数组 */
(target?: number, start?: number, end?: number | undefined)=> T[]
copyWithin
将数组中的,从start
位置开始至end
位置(不包含end
处的元素)结束的元素,进行浅复制,并从target
处开始覆盖该数组。最后将修改后的原数组返回。
//不传入参数时,都使用默认值,相当于 [1, 2, 3].copyWithin(0,0,3) //首先复制了数组中的[ 0, 3 )的部分,即[1,2,3] //然后从数组的下标0处开始覆盖,覆盖之后得到[1, 2, 3] console.log([1, 2, 3].copyWithin()); //[ 1, 2, 3 ] //从数组的下标1处开始覆盖,复制的部分为[1, 2, 3],从原数组的下标1处开始覆盖,原数组只剩余两个位置,所以结果为[ 1, 1, 2 ] console.log([1, 2, 3].copyWithin(1)); //[ 1, 1, 2 ]
有几点需要注意的是:
第一,copyWithin
会修改原数组,返回的是修改之后的原数组,而不是创建的一个新数组。
const arr = [1, 2, 3]; const res = arr.copyWithin(1, 0); console.log(arr === res, arr); //true [ 1, 1, 2 ]
第二,当target>=arr.length
时,不会发生复制行为,直接返回没有进行任何修改的原数组。
const arr = [1, 2, 3]; const res = arr.copyWithin(6, 2); //返回没有进行任何修改的原数组 console.log(arr === res, arr); //true [ 1, 2, 3 ]
第三,当target
、start
或者end
传入负数时,代表此时的从数组末尾开始计算,假如传入的值是-1
,就代表倒数第一个元素的位置。
const arr = [1, 2, 3]; const res = arr.copyWithin(-2, 2); //从下标2开始复制得到的复制部分为 [ 3 ] //从-2,即倒数第二个元素开始覆盖,就得到了 [1, 3, 3 ] console.log(arr === res, arr); //true [ 1, 3, 3 ]
- Array.prototype.fill
函数类型:
/** * @author: forceddd * @desc: 将数组从start位置开始至end结束(不包括end)的部分都赋值为value * @param {any} value 用来给数组中元素赋值的值 * @param {number} start 赋值的起始位置,默认为0 * @param {number} end 赋值的结束位置,默认为数组的长度 * @return {*} 返回值为赋值之后的原数组 */ (value?: any, start?: number, end?: number) => any[];
fill
将数组从start
位置开始至end
结束(不包括end
)的部分都赋值为value
,然后将数组返回。
console.log(Array(4).fill()); //[ undefined, undefined, undefined, undefined ] console.log(Array(4).fill(0)); //[ 0, 0, 0, 0 ] console.log(Array(4).fill(0, 1, 2)); //[ <1 empty item>, 0, <2 empty items> ]
fill
和copyWithin
一样,返回的也是原数组,并且当start
或者end
为负数时,也是和copyWithin
相同的处理方式。
除此之外,从代码中也可以看出,fill
会产生空位元素,而且如果value
值为对象,则赋值时使用的是对象的引用。换句话说:
const v = []; const arr = Array(4).fill(v); console.log(arr[0] === arr[1]); //true arr[0].push(1); console.log(arr); //[ [ 1 ], [ 1 ], [ 1 ], [ 1 ] ]
- Array.prototype.find
函数类型:
/** * @author: forceddd * @desc:找到数组中使得findFn返回值为true的第一个元素并将其返回 * @param {FindFn} findFn 数组每一项上执行的函数 * @param {any} thisArg 回调函数findFn中的this对象 * @return {*} */ (findFn: FindFn, thisArg?: any) => any; /** * @author: forceddd * @param {any} item 数组中的元素 * @param {number} index 当前元素在数组中的下标 * @param {any} arr 数组实例 * @return {boolean} */ type FindFn = (item: any, index: number, arr: any[]) => boolean;
find
会返回数组中使得回调函数返回值为true
的第一个元素,如果没有这样的元素,会返回undefined
。
console.log([1, 2, 3].find((v) => v >= 2)); //2
在ES6之前,使用
需要注意的是,indexOf
方法需要进行严格匹配(===
)才能判定元素是否存在,使用some
方法虽然可以自定义比对的回调函数,但是只能返回boolean
,而不能获得元素本身。find
中回调函数的执行次数是根据数组的下标决定的,下标[ 0 , arr.length - 1 ]
的范围都会执行一次,它不关心当前元素的值,所以在当前元素是空位元素的时候,find
中的回调函数会把元素值作为undefined
执行一次,这和map
、forEach
等函数是不同的。
[1, , 3, 4].find((v) => console.log(v)); //1 undefined 3 4 [1, , 3, 4].map((v) => console.log(v)); //1 3 4
另外,当find
中的回调函数第一次执行时,它的执行次数[ 0 , arr.length - 1 ]
就已经确定了,并且不会再改变。这也就意味着,假设我们要处理的数组arr
长度为5
,在回调函数执行的过程中,我们修改了arr
,使其长度成为了10
,或者我们删除了一个元素,使其长度变为4
,回调函数都会执行5
次。当元素被删除的情况下,回调函数在执行时访问不到该元素,会以undefined
代替该元素继续执行。
[1, 2, 3, 4].find((v, i, arr) => { //删除一个元素 i === 0 && arr.pop(); console.log({ v, i }); }); //{ v: 1, i: 0 } //{ v: 2, i: 1 } //{ v: 3, i: 2 } //{ v: undefined, i: 3 }
- Array.prototype.findIndex
findIndex
与find
方法基本相同,只有返回值有区别,findIndex
返回的是符合条件的元素下标,在没有这样的元素时,会返回-1
。
- keys,values,entries
函数类型:
type Keys = () => Iterator
; type Values = () => Iterator; type Entries = () => Iterator;
【ES6新增API(Array篇(二))】keys
,values
,entries
都不需要任何参数,返回的都是一个迭代器。不同点在于迭代器中的值分别是数组的下标、数组的元素以及数组的下标和数组元素组成的[ i , v ]
形式的键值对。
const it = ['a', 'b', 'c'].entries(); console.log(it.next()); //{ value: [ 0, 'a' ], done: false } console.log(it.next()); //{ value: [ 1, 'b' ], done: false } console.log(it.next()); //{ value: [ 2, 'c' ], done: false } console.log(it.next()); // { value: undefined, done: true }
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- (二)ES6第一节变量(let|(二)ES6第一节变量(let,const)
- 六步搭建ES6语法环境
- Excel|Excel 2013 新增功能之瞬间填充整列数据!
- 【译】Rails|【译】Rails 5.0正式发布(Action Cable,API模式等)
- 前端|web前端dya07--ES6高级语法的转化&render&vue与webpack&export
- ElasticSearch6.6.0强大的JAVA|ElasticSearch6.6.0强大的JAVA API详解
- 12.新增腾讯的统计(以渠道来源说明)
- 前端开发|Vue2.x API 学习
- HTML5新增选择器属性方法