Array.prototype 本身是 Array
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Array.prototype // [constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]
Array.prototype.constructor // ƒ Array() { [native code] }
Array.prototype.constructor.name // 'Array'
let arr = [1, 2, 3]
arr.shift() // 1
arr // [2, 3]
let arr2 = arr.slice(0)
arr2 // [2, 3]
arr === arr2 // false
let arr = [{a: 1}]
let arr2 = arr.slice(0)
arr == arr2 // false
arr === arr2 // false
arr2[0].a = 2
arr2 // [{a: 2}]
arr // [{a: 2}
[1].concat([2], [3]) // [1, 2, 3]
[].concat.call([1], [2], [3]) // equal to [1].concat([2], [3])
[1].concat(2, 3, {a: 1}) // [1, 2, 3 {a: 1}]
[].concat.call([1], 2, 3, {a: 1}) // equal to [1].concat(2, 3, {a: 1})
Array.prototype.push
function ArrayPush() {
var n = TO_UINT32( this.length ); // 被 push 的对象的 length
var m = %_ArgumentsLength(); // push 的参数个数
for (var i = 0; i < m; i++) {
this[ i + n ] = %_Arguments( i ); // 复制元素 (1)
}
this.length = n + m; // 修正 length 属性的值 (2)
return this.length;
};
通过这段代码可以看到,Array.prototype.push
实际上是一个属性复制的过程,把参数按照
下标依次添加到被 push
的对象上面,顺便修改了这个对象的 length
属性。至于被修改的对象是
谁,到底是数组还是类数组对象,这一点并不重要。《JavaScript设计模式与开发实践》
let a = {}
Array.prototype.push.call(a, 'first')
a // {0: 'first', length: 1}
Array.prototype.push.call(a, 'second')
a // {0: 'first', 1: 'second', length: 2}
var a = {};
Array.prototype.push.call( a, 'first' );
alert ( a.length ); // 输出:1
alert ( a[ 0 ] ); // first
这段代码在绝大部分浏览器里都能顺利执行,但由于引擎的内部实现存在差异,如果在低版
本的 IE 浏览器中执行,必须显式地给对象 a 设置 length 属性:
var a = {
length: 0
};
“任意”对象至少要满足 2 点:
1. 对象本身要可以存取属性
2. 对象的 length 属性可读写
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype
Array.prototype.find
const arr = [100, 200, 300, 400]
const valueOfMatchedElement = arr.find(function (value, index, array) {
console.log(this) // {hobby: 'dance'}
// return value > 200 // 300
return value > 2000 // undefined
}, {hobby: 'dance'})
document.write(valueOfMatchedElement)
https://codepen.io/MonguDykrai/pen/YRqbgW
Array.prototype.findIndex
const arr = [100, 200, 300, 400, 500]
const indexOfMatchedElement = arr.findIndex(function (value, index, array) {
console.log(this) // {name: 'jack'}
return value > 300 // 3
// return value > 3000 // -1
}, {name: 'jack'})
document.write(indexOfMatchedElement)
https://codepen.io/MonguDykrai/pen/EOyxqZ
Array.of
console.log(Array.of(7)) // [7]
// console.log(Array.of(undefined)) // [undefined]
console.log(Array.of(1, 2, 3)) // [1, 2, 3]
console.log(Array(7)) // [empty × 7]
// console.log(Array(undefined)) // [undefined]
console.log(Array(1, 2, 3)) // [1, 2, 3]
https://codepen.io/MonguDykrai/pen/QJExGp
Array.from
const { toString } = Object.prototype
const lis = document.querySelectorAll('li')
console.log(toString.call(lis)) // [object NodeList]
const lisArray = Array.from(lis)
console.log(lisArray) // [li, li, li]
Array.from(lis, function (value, index, array) {
console.log(this) // {Disney: "Anne"}
/**
* <li>1</li> 0 undefined
* <li>2</li> 1 undefined
* <li>3</li> 2 undefined
*/
console.log(value, index, array)
}, {Disney: 'Anne'})
console.log(lis)
https://codepen.io/MonguDykrai/pen/GwqGOp
Array.prototype.entries
The entries() method returns a new Array Iterator object that contains the key/value pairs
for each index in the array.
var array1 = ['a', 'b', 'c'];
var iterator1 = array1.entries();
console.log(iterator1)
console.log(iterator1.next().value);
console.log(iterator1.next().value);
console.log(iterator1.next().value);
console.log(iterator1.next().value);
image.png
Codepen: https://codepen.io/MonguDykrai/pen/KrEXjW
var array1 = ['a', 'b', 'c'];
for (let [index, value] of array1.entries()) {
console.log(index, value)
}
var iterator1 = array1.entries();
for (let v of iterator1) {
console.log(v)
}
image.png
Codepen: https://codepen.io/MonguDykrai/pen/pQYdvw
Array.prototype.values
const array1 = ['a', 'b', 'c']
const iterator = array1.values()
console.log(iterator)
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
image.png
https://codepen.io/MonguDykrai/pen/xQeqbo
const array1 = ['a', 'b', 'c']
for (let elem of array1.values()) {
console.log(elem)
}
const iterator = array1.values()
for (let v of iterator) {
console.log(v)
}
https://codepen.io/MonguDykrai/pen/wQZJKr
Array.prototype.keys
const array1 = ['a', 'b', 'c']
const iterator = array1.keys()
console.log(iterator)
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
image.png
https://codepen.io/MonguDykrai/pen/NEmpNX
const array1 = ['a', 'b', 'c']
for (let k of array1.keys()) {
console.log(k)
}
const iterator = array1.keys()
for (let k of iterator) {
console.log(k)
}
https://codepen.io/MonguDykrai/pen/BGEWzw
Array.prototype.flat
flat()
默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将 flat()
方法的参数写成一个整数,表示想要拉平的层数,默认为 1
。
如果不管有多少层嵌套,都要转成一维数组,可以用 Infinity
关键字作为参数。
const arr = [1, 2, [3, 4]].flat()
console.log(arr)
const arr2 = [1, 2, 3, [4 ,5 ,[6, 7]]].flat(3)
console.log(arr2)
const arr3 = ['a', ['b', ['c', ['d', ['e']]]]].flat(5)
console.log(arr3)
const arr4 = [1, [2, [3, [4, [5, [6, [7, [8, [9]]]]]]]]].flat(Infinity)
console.log(arr4)
// 如果原数组有空位,flat()方法会跳过空位。
const arr5 = [1, 2, 3, , 5].flat()
console.log(arr5)
https://codepen.io/MonguDykrai/pen/gQymxx
http://es6.ruanyifeng.com/#docs/array#%E6%95%B0%E7%BB%84%E5%AE%9E%E4%BE%8B%E7%9A%84-flat%EF%BC%8CflatMap
Array.prototype.flatMap
const arr = [1, 2, 3, 4]
arr.flatMap(function (val, index, array) {
console.log(val, index, array)
})
const res = [2, 3, 4].flatMap(function (x) {
console.log(this) // {name: 'rose'}
return [x, x * 2]
}
, {name: 'rose'})
// [[2, 4], [3, 6], [4,8]].flat() -> [2, 4, 3, 6, 4, 8]
console.log(res)
const res2 = [1, 2, 3].flatMap(function (x) {
return [[x * 2]]
})
// [[[2]], [[4]], [[6]]].flat() -> [[2], [4], [6]]
console.log(res2)
https://codepen.io/MonguDykrai/pen/vQMxzZ
http://es6.ruanyifeng.com/#docs/array#%E6%95%B0%E7%BB%84%E5%AE%9E%E4%BE%8B%E7%9A%84-flat%EF%BC%8CflatMap
网友评论