前言
ES6
新增了很多属性、方法以及某些特性,本系列主要通过模拟实现的方式来重学ES6
,以便帮助自己更深入的的理解那些新增的东西。
本文目标: 通过模拟实现,深入理解ES6数组身上新增的东西
说明: 文中对一下方法简单介绍,然后完成模拟实现
模拟实现数组新增的东西
静态方法
Array.from()
介绍
参数: 第一个参数接收一个类数组或其他部署了Iterator接口的数据结构,第二个可选参数接受一个函数,作用类似map
作用: 把接收的第一个参数转成真数组,并可通过第2个参数进行整理
返回值: 返回新的数组,不改变原对象
模拟实现:Array._from()
Array._from = (likeArray, callback) => {
let res = [].slice.call(likeArray)
return (typeof callback == 'function') ? res.callback() : res
}
console.log(Array._from('asd'))// ["a", "s", "d"]
console.log(Array.from('asd'))// ["a", "s", "d"]
let divs = document.querySelectorAll('div')
console.log(Array._from(divs))//[div, div, div]
console.log(Array.from(divs))//[div, div, div]
Array.of()
介绍
参数: 可接收n个参数
作用: 将一组参数转成数组
返回值: 返回该数组
模拟实现:Array._of()
Array._of = (...args) => args;
console.log(Array._of(1, 2, 3))//[1,2,3]
console.log(Array.of(1, 2, 3))//[1,2,3]
实例方法
copyWithin()
介绍
参数: 可接收三个参数,且参数一般为数值,如果不是数值会转成数值,如果出现负数,表示倒数第几位。第一个参数表示从该位置开始替换数据,第二个参数表示从该位置开始读取数据(默认为0),第三个表示读取数据到该位置(默认为数组长度)
作用: 将数组中某位置到某位置的数据复制,然后到从指定位置开始替换对应长度的数据
返回值: 返回当前数组,即会改变原数组
模拟实现:_copyWithin()
Array.prototype._copyWithin = function (target, start = 0, end = this.length) {
// 1. 将负值情况处理了
if (target < 0) {
target += this.length
}
if (start < 0) {
start += this.length
}
if (end < 0) {
end += this.length
}
// 2.找到要拷贝的值,并在指定位置逐一替换
for (let index = start; index < end; index++) {
// this[index];//需要拷贝的值
if (target < this.length) {
console.log(this[target],this[index])
this[target] = this[index];
target++
}
}
return this
}
console.log([1, 2, 3, 4].copyWithin(2))//[1, 2, 1, 2]
console.log([1, 2, 3, 4]._copyWithin(2))//[1, 2, 1, 2]
find()
介绍
参数: 第一个参数是一个callback回调函数,第二个参数是this指向
作用: 遍历数组成员并执行回调,返回第一个符合条件的数组成员
返回值: 返回第一个执行回调后返回值为true的成员没有找到返回undefined
模拟实现:_find()
Array.prototype._find = function (callback, self) {
if (typeof callback === 'function') {
if (this.length) {
for (let i = 0; i < this.length; i++) {
// 找出每一个成员传入回调中,执行如果为真,则返回该值
if (callback.call(self, this[i], i, this)) {
return this[i]
}
}
}
}
}
let a = [1, 2, 3]
console.log(a._find(function (val, index, arr) { return val == 1 }));//1
console.log(a.find(function (val, index, arr) { return val == 1 }));//1
findIndex()
介绍
参数: 第一个参数是一个callback回调函数,第二个参数是this指向
作用: 跟find方法类似,只不过是查找第一个符合条件的数组成员的index值
返回值: 返回第一个符合条件的成员的index
模拟实现:_findIndex()
Array.prototype._findIndex = function (callback, self) {
if (typeof callback === 'function') {
if (this.length) {
for (let i = 0; i < this.length; i++) {
// 找出每一个成员传入回调中,执行如果为真,则返回该值
if (callback.call(self, this[i], i, this)) {
return i
}
}
}
}
}
let a = [1, 2, 3]
console.log(a._findIndex(function (val, index, arr) { return val == 1 }));//0
console.log(a.findIndex(function (val, index, arr) { return val == 1 }));//0
fill()
介绍
参数: 可接收三个参数,分别表示要填充的东西、填充的起始位置、填充的结束位置;后两个选填,默认值分别为0和数组长度
作用: 用于填充数组,将要填充的东西填充到指定的位置
返回值: 返回填充修改后的数组,即会改变原数组
模拟实现:_fill()
Array.prototype._fill = function (data, start = 0, end = this.length) {
// 处理负值
if (start < 0) {
start += this.length
}
if (end < 0) {
end += this.length
}
// 填充
for (let i = start; i < end; i++) {
this[i] = data;
}
return this
}
console.log(new Array(5)._fill('a', -2))//[empty × 3, "a", "a"]
console.log(new Array(5).fill('a', -2))//[empty × 3, "a", "a"]
entries(),keys() , values()
介绍
三者差不多,就放一起按说了
参数: 无
作用: keys()是对键名的遍历,values()是对键值的遍历,entries()是对键值对的遍历
返回值: 都返回一个遍历器对象
模拟实现:_keys()
Array.prototype._keys = function (){
let temp = []
for (let i = 0; i < this.length; i++) {
temp.push(i)
}
return temp[Symbol.iterator]()
}
let arr = ['a','b','c']
console.log(arr._keys(),arr.keys());
for (const iterator of arr._keys()) {
console.log(iterator);
}
for (const iterator of arr.keys()) {
console.log(iterator);
}
结果如下:
模拟实现:_values()
Array.prototype._values = function (){
let temp = []
for (let i = 0; i < this.length; i++) {
temp.push(this[i])
}
return temp[Symbol.iterator]()
}
let arr = ['a','b','c']
for (const i of arr._values()) {
console.log(i);
}
for (const i of arr.values()) {
console.log(i);
}
模拟实现:_entries()
Array.prototype._entries = function (){
let temp = []
for (let i = 0; i < this.length; i++) {
temp.push([i,this[i]])
}
return temp[Symbol.iterator]()
}
includes()
介绍
参数: 接收一个需要判断的值
作用: 用于判断给定值是否包含在数组中
返回值: 返回true或false
模拟实现:_includes()
Array.prototype._includes = function (x) {
for (let i = 0; i < this.length; i++) {
if (Number.isNaN(x) && Number.isNaN(this[i])) {
return true
}
if (x === this[i]) {
return true
}
}
return false
}
let arr = [1,2,3,4,NaN]
console.log(arr._includes(2))//true
console.log(arr._includes(NaN))//true
console.log(arr._includes(5))//false
flat()
介绍
参数: 接收一个整数
作用: 用于将数组拉平或者叫拍平,拍平的深度取决于传递的参数,默认为2,表示拍平二维数组
返回值: 返回拍平后的数组,不改变原始数组
模拟实现:_flat()
Array.prototype._flat = function (n = 1) {
return this.reduce((acc, val) => {
return acc.concat(Array.isArray(val) && n > 0 ?
val.flat(--n) : Array.isArray(val) ? [val] : val);
}, [])
}
let arr = [1, [2, 3], ['a', 'b', ['c', 'd']]]
console.log(arr._flat(3))//[1, 2, 3, "a", "b", "c", "d"]
END
以上就是数组身上新增的一些东西的模拟实现!
真正的实现可能跟我写的不一样,不过没有关系,我们只要熟知这些方法具体干了什么,也就达到了这次学习的目的了!
如有疑问或建议,希望可以留言告知,感谢你!!