跳到主要内容

all

2023年06月08日
柏拉文
越努力,越幸运

Array.prototype.concat()


Array.prototype.concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

语法

var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
  • valueN可选: 数组和/或值,将被合并到一个新的数组中。如果省略了所有valueN参数,则concat会返回调用此方法的现存数组的一个浅拷贝。
    • 如果valueN字符串数字布尔(不是String,Number 和 Boolean 对象),concat将字符串和数字的值复制到新数组中。
    • 如果valueN对象引用,concat将对象引用复制到新数组中。 原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。

返回值

新的 Array 实例。

应用

  • 合并多个值

    const array = [1,2,3,4];
    const arrayCopy = array.concat('哈哈','哇哇');
    console.log(arrayCopy); //  [1, 2, 3, 4, '哈哈', '哇哇']
  • 合并多个数组

    const array = [1,2,3,4];
    const arrayCopy = array.concat(['哈哈','哇哇']);
    console.log(arrayCopy); //  [1, 2, 3, 4, '哈哈', '哇哇']
  • 合并多个值和数组

    const array = [1, 2, 3, 4];
    const arrayCopy = array.concat(["哈哈", "哇哇"], "哈哈", "哇哇");
    console.log(arrayCopy); //  [1, 2, 3, 4, '哈哈', '哇哇', '哈哈', '哇哇']

原理

Array.prototype.copyWithin()


Array.prototype.copyWithin() 浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度

语法

arr.copyWithin(target[, start[, end]])
  • target: 0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。如果 target 大于等于 arr.length,将会不发生拷贝。如果 target 在 start 之后,复制的序列将被修改以符合 arr.length。
  • start: 0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。如果 start 被忽略,copyWithin 将会从0开始复制。
    • 如果start < 0 ,则start = 数组长度+start
  • end: 0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。如果 end 被忽略,copyWithin 方法将会一直复制至数组结尾(默认为 arr.length)。
    • 如果end < 0 ,则end = 数组长度+end

返回值

改变后的数组。

应用

  • 拷贝数组

    const array = [1, 2, 3, 4];
    const arrayCopy = array.copyWithin(3,0,2);
    console.log(array); // [1, 2, 3, 1]
    console.log(arrayCopy); // [1, 2, 3, 1]

原理(Polyfill)

Array.prototype.copyWithin = function(target,start,end){
if(this == null){
throw new TypeError('this is null or not defined');
}
var object = Object(this);
var length = object.length >>> 0;
var targetCopy = target >> 0;
targetCopy = targetCopy < 0 ? Math.max(length+targetCopy,0):Math.min(targetCopy,length);
var startCopy = start >> 0;
startCopy = startCopy < 0 ? Math.max(length+startCopy,0):Math.min(startCopy,length);
var endCopy = end === undefined ? length : end >> 0;
endCopy = endCopy<0 ? Math.max(length+endCopy,0):Math.min(endCopy,length);
var count = Math.min(endCopy - startCopy,length - targetCopy);
var direction = 1;
if(startCopy < targetCopy && targetCopy < (startCopy + count)){
direction = -1;
startCopy += count -1;
targetCopy += count -1 ;
}
while(count > 0){
if(startCopy in object){
object[targetCopy] = object[startCopy];
}else{
delete object(targetCopy);
}
startCopy += direction;
targetCopy += direction;
count --;
}
return object;
}

var array = [1,2,3,4,5,6];
array.copyWithin(2,0);
console.log(array);

Array.prototype.entries()


Array.prototype.entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。

语法

arr.entries()

返回值

一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(proto:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。

应用

  • 运行迭代器: 注意以下几点

    • **对于迭代器.next()**的返回值: { value: Array(2), done: false }

      • next.done用于指示迭代器是否完成:在每次迭代时进行更新而且都是false,直到迭代器结束done才是true。

      • next.value是一个["key","value"]的数组,是返回的迭代器中的元素值。

    • 对于遍历次数 应该是[0,length+1)。因为遍历length+1次才可以遍历完毕。

    var array = [1, 2, 3, 4, 5, 6];
    var iterator = array.entries();
    for (var i = 0; i < array.length + 1; i++) {
    var item = iterator.next();
    console.log(item); // {value: Array(2), done: false} {value: Array(2), done: false} …… {value: Array(2), done: false} {value: undefined, done: true}
    console.log(item.value); // [0, 1] [1, 2] …… [5, 6] undefined
    if (item.done !== true) {
    console.log(item.value[1]); // 1 2 3 4 5 6
    }
    }

原理

Array.prototype.every()


Array.prototype.every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。Array.prototype.every() 和数学中的所有类似,当所有的元素都符合条件才会返回true。正因如此,若传入一个空数组,无论如何都会返回true

危险

[].some()[].every() 的区别:

  • [].some() 无论如何都会返回false
  • [].every() 无论如何都会返回true

语法

arr.every(callback(element[, index[, array]])[, thisArg])
  • callback: 用来测试每个元素的函数,它可以接收三个参数:
    • element: 用于测试的当前值。
    • index: 用于测试的当前值的索引。
    • array: 调用 every 的当前数组。
  • thisArg: 执行 callback 时使用的 this 值。

返回值

如果回调函数的每一次返回都为 true 值,返回 true ,否则返回 false。

应用

  • 检测所有元素是否都大于10

    const array = [1,2,3,4,5,11,12,13];
    console.log(array.every(function(item,index,array){
    return item >= 10;
    })); // false

原理

Array.prototype.every = function (callback, thisArg) {
if (this == null) {
throw new TypeError("this is null or not defined");
}
if (typeof callback !== "function") {
throw new TypeError("callback is not function");
}
var object = Object(this);
var length = object.length >>> 0;
var index = 0;
while (index < length) {
if (index in object) {
var value = object[index];
var result = callback.call(thisArg, value, index, object);
if (!result) {
return false;
}
}
index++;
}
return true;
};

const array = [1, 2, 3, 4, 5, 11, 12, 13];
console.log(
array.every(function (item, index, array) {
return item >= 10;
})
); // false

Array.prototype.fill()


Array.prototype.fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

语法

arr.fill(value[, start[, end]])
  • value: 用来填充数组元素的值
  • start: 起始索引,默认值为0
    • 如果 start<0,则start = 数组长度 + start
  • end: 终止索引,默认值为this.length
    • 如果 end<0,则start = 数组长度 + end

返回值

修改后的数组。

应用

  • 对象批量添加属性: 通过call改变Array.prototype.fillthis指针方可实现

    const obj = {
    length:3
    }

    Array.prototype.fill.call(obj,'哈哈')
    console.log(obj); // {0: '哈哈', 1: '哈哈', 2: '哈哈', length: 3}
  • 为数组填充引用类型: fill的参数为引用类型,会导致都执行同一个引用类型

    const array = new Array(10);
    array.fill({});
    array[0].name = 'a0';
    console.log(array[1],array[9]); // {name: 'a0'} {name: 'a0'}

原理(Polyfill)

Array.prototype.fill = function(value,start,end){
if(this == null){
throw new TypeError('this is null or undefined');
}
var object = Object(this);
var length = object.length >>> 0;
var startCopy = start >> 0;
startCopy = startCopy < 0 ? Math.max(startCopy+length,0):Math.min(startCopy,length);
var endCopy = end === undefined ? length : end >> 0;
endCopy = endCopy < 0 ? Math.max(endCopy+length,0):Math.min(endCopy,length);
while(startCopy < endCopy){
object[startCopy++] = value;
}
return object;
}

const array1 = new Array(10);
array1.fill(10);
console.log(array1);

const array2 = new Array(10);
array2.fill(10, -4);
console.log(array2);

const array3 = new Array(10);
array3.fill(10, -4, 12);
console.log(array3);

Array.prototype.find()


Array.prototype.find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

语法

arr.find(callback[, thisArg])
  • callback: 在数组每一项上执行的函数,接收 3 个参数:
    • element: 当前遍历到的元素。
    • index可选: 当前遍历到的索引。
    • array可选: 数组本身。
  • thisArg可选: 执行回调时用作this 的对象。

返回值

数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。

应用

  • 查找名字叫柏拉图的元素

    var array = [
    {
    name:'柏拉图'
    },
    {
    name:'柏拉文'
    }
    ]
    var item = array.find(function(value,index,array){
    return value.name === '柏拉图'
    });
    console.log(item); // array.html:22 {name: '柏拉图'}

原理(Polyfill)

Array.prototype.find = function(callback,thisArg){
if(this == null){
throw new TypeError('this is null or not defined');
}
if(typeof callback !== 'function'){
throw new TypeError('callback is not function');
}
var object = Object(this);
var length = object.length >>> 0;
var index = 0;
while(index < length){
var value = object[index];
var result = callback.call(thisArg,value,index,object);
if(result){
return value;
}
index++;
}
return undefined;
}

var array = [
{
name:'柏拉图'
},
{
name:'柏拉文'
}
]
var item = array.find(function(value,index,array){
return value.name === '柏拉图'
});
console.log(item); // array.html:22 {name: '柏拉图'}

Array.prototype.findIndex()


**Array.prototype.findIndex()**方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

语法

arr.findIndex(callback[, thisArg])
  • callback: 针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:
    • element: 当前元素。
    • index: 当前元素的索引。
    • array: 调用findIndex的数组。
  • thisArg可选: 执行callback时作为this对象的值。

返回值

数组中通过提供测试函数的第一个元素的索引。否则,返回-1

应用

  • 查找名字叫柏拉图的元素

    var array = [
    {
    name: "柏拉图",
    },
    {
    name: "柏拉文",
    },
    ];
    var index = array.findIndex(function (value, index, array) {
    return value.name === "柏拉图";
    });
    console.log(index); // 0

原理(Polyfill)

Array.prototype.findIndex = function (callback, thisArg) {
if (this == null) {
throw new TypeError("this is null or not defined");
}
if (typeof callback !== "function") {
throw new TypeError("callback is not function");
}
var object = Object(this);
var length = object.length >>> 0;
var index = 0;
while (index < length) {
var value = object[index];
var result = callback.call(thisArg, value, index, object);
if (result) {
return index;
}
index++;
}
return -1;
};

var array = [
{
name: "柏拉图",
},
{
name: "柏拉文",
},
];
var index = array.findIndex(function (value, index, array) {
return value.name === "柏拉图";
});
console.log(index); // 0

Array.prototype.flat()


Array.prototype.flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

语法

var newArray = arr.flat([depth])
  • depth 可选: 指定要提取嵌套数组的结构深度,默认值为 1。

返回值

一个包含将数组与子数组中所有元素的新数组。

应用

  • 扁平化嵌套数组

    var arr1 = [1, 2, [3, 4]];
    arr1.flat();
    // [1, 2, 3, 4]

    var arr2 = [1, 2, [3, 4, [5, 6]]];
    arr2.flat();
    // [1, 2, 3, 4, [5, 6]]

    var arr3 = [1, 2, [3, 4, [5, 6]]];
    arr3.flat(2);
    // [1, 2, 3, 4, 5, 6]

    //使用 Infinity,可展开任意深度的嵌套数组
    var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
    arr4.flat(Infinity);
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • 利用扁平化移除数组空项

    var arr4 = [1, 2, , 4, 5];
    arr4.flat();
    // [1, 2, 4, 5]

替代方案

  • 使用扩展运算符实现一层扁平

    function flat(array){
    return [].concat(...array);
    }

    const array = [1,[2,[3,4,[5,6,7],8,9],10,11],12,13,14,[15,[16]]];
    console.log(flat(array)); // [1, 2, Array(5), 10, 11, 12, 13, 14, 15, Array(1)]
  • 使用 reduceconcat 实现一层扁平

    function flat(array){
    return array.reduce(function(accumulator,currentValue,arr){
    return accumulator.concat(currentValue);
    },[]);
    }

    const array = [1,[2,[3,4,[5,6,7],8,9],10,11],12,13,14,[15,[16]]];
    console.log(flat(array)); // [1, 2, Array(5), 10, 11, 12, 13, 14, 15, Array(1)]
  • 使用 reduce + concat 递归实现深层扁平

    完整写法
    function flat(array, deep = 1) {
    if (deep > 0) {
    return array.reduce(function (accumulator, currentValue, arr) {
    if (Array.isArray(currentValue)) {
    return accumulator.concat(flat(currentValue, deep - 1));
    } else {
    return accumulator.concat(currentValue);
    }
    }, []);
    } else {
    return array.slice();
    }
    }

    const array = [
    1,
    [2, [3, 4, [5, 6, 7], 8, 9], 10, 11],
    12,
    13,
    14,
    [15, [16]],
    ];
    console.log(flat(array, 2)); // [1, 2, 3, 4, Array(3), 8, 9, 10, 11, 12, 13, 14, 15, 16]
    console.log(flat(array, Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    function flat(array, deep = 1) {
    return deep > 0
    ? array.reduce(
    (accumulator, currentValue, arr) =>
    Array.isArray(currentValue)
    ? accumulator.concat(flat(currentValue, deep - 1))
    : accumulator.concat(currentValue),
    []
    )
    : array.slice();
    }

    const array = [
    1,
    [2, [3, 4, [5, 6, 7], 8, 9], 10, 11],
    12,
    13,
    14,
    [15, [16]],
    ];
    console.log(flat(array, 2)); // [1, 2, 3, 4, Array(3), 8, 9, 10, 11, 12, 13, 14, 15, 16]
    console.log(flat(array,Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  • 使用 forEach 递归实现深层扁平

    function flat(array, deep = 1) {
    const result = [];
    const recurse = (currentArray,currentDeep)=>{
    currentArray.forEach(function(value,index,arr){
    if(Array.isArray(value) && currentDeep > 0){
    recurse(value,currentDeep-1);
    }else{
    result.push(value);
    }
    });
    }
    recurse(array,deep);
    return result;
    }

    const array = [
    1,
    [2, [3, 4, [5, 6, 7], 8, 9], 10, 11],
    12,
    13,
    14,
    [15, [16]],
    ];
    console.log(flat(array, 2)); // [1, 2, 3, 4, Array(3), 8, 9, 10, 11, 12, 13, 14, 15, 16]
    console.log(flat(array, Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  • 使用堆栈 循环迭代实现深层扁平

    function flat(array) {
    const stack = [...array];
    const result = [];
    while(stack.length){
    const value = stack.pop();
    if(Array.isArray(value)){
    stack.push(...value);
    }else{
    result.push(value);
    }
    }
    return result.reverse();
    }

    const array = [
    1,
    [2, [3, 4, [5, 6, 7], 8, 9], 10, 11],
    12,
    13,
    14,
    [15, [16]],
    ];
    console.log(flat(array, 2)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    console.log(flat(array, Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  • 使用Generator循环迭代实现深层扁平

    function* flat(array) {
    for(let item of array){
    if(Array.isArray(item)){
    yield* flat(item);
    }else{
    yield item;
    }
    }
    }

    const array = [
    1,
    [2, [3, 4, [5, 6, 7], 8, 9], 10, 11],
    12,
    13,
    14,
    [15, [16]],
    ];
    console.log([...flat(array, 2)]); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    console.log([...flat(array, Infinity)]); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

Array.prototype.flatMap()


flatMap()Array.prototype.flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与map连着深度值为1的flat几乎相同,但flatMap通常在合并成一种方法的效率稍微高一些。

语法

var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
  • callback: 可以生成一个新数组中的元素的函数,可以传入三个参数:
    • currentValue: 当前正在数组中处理的元素
    • index: 可选的。数组中正在处理的当前元素的索引。
    • array: 可选的。被调用的 map 数组
  • thisArg: 可选的。执行 callback 函数时 使用的this 值。

返回值

一个新的数组,其中每个元素都是回调函数的结果,并且结构深度depth值为1。

应用

  • 将元素转化为数组

    const array = [1,2,3,4,5,6,7,8];
    const arrayCopy = array.flatMap(function(value,index,arr){
    return [[value*2]]
    });
    console.log(arrayCopy); //  [Array(1), Array(1), Array(1), Array(1), Array(1), Array(1), Array(1), Array(1)]

原理

Array.from()


Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。**Array.from()**可以通过以下方式来创建数组对象:

  • 伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
  • 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

语法

Array.from(arrayLike[, mapFn[, thisArg]])
  • arrayLike: 想要转换成数组的伪数组对象或可迭代对象。
  • mapFn: 如果指定了该参数,新数组中的每个元素会执行该回调函数。Array.from()方法有一个可选参数 mapFn,让你可以在最后生成的数组上再执行一次map法后再返回。也就是说Array.from(obj, mapFn, thisArg)就相当于Array.from(obj).map(mapFn, thisArg)
  • thisArg: 可选参数,执行回调函数 mapFn 时 this 对象。

返回值

一个新的数组实例。

应用

  • String生成数组

    const result = Array.from('柏拉图');
    console.log(result); // ['柏', '拉', '图']
  • Set生成数组

    const set = new Set(['柏','拉','图']);
    const result = Array.from(set);
    console.log(result); // ['柏', '拉', '图']
  • Map生成数组

    const map = new Map([['name','名字'],['age','年龄']]);
    const result = Array.from(map);
    console.log(result); //  [Array(2), Array(2)]

原理(Polyfill)

无法使用Polyfill实现真正的的迭代器,该实现不支持规范中定义的泛型可迭代元素。以下实现只支持类数组

function createArrayLike (a,b,c,d,e,f,g){
return arguments;
}
Array.from = function(arrayLike,mapCallback,thisArg){
if(arrayLike == null){
throw new TypeError('Array.from: the first argument must be a array-like');
}
if(mapCallback !==undefined && Object.prototype.toString.call(mapCallback) !== "[object Function]"){
throw new TypeError('Array.from: the second argument must be a function');
}
var object = Object(arrayLike);
var length = object.length >>> 0;
var result = new Array(length);
var index = 0;
while(index < length){
var value = object[index];
if(mapCallback){
result[index++] = mapCallback.call(thisArg,value,index);
}else{
result[index++] = value;
}
}
result.length = index;
return result;
}
const arrayLike = createArrayLike(1,2,3,4,5,6,7);
console.log(arrayLike); // Arguments(7) [1, 2, 3, 4, 5, 6, 7, callee: ƒ, Symbol(Symbol.iterator): ƒ]
const result = Array.from(arrayLike,function(value,index){
return value+'哈哈'
});
console.log(result); //  ['1哈哈', '2哈哈', '3哈哈', '4哈哈', '5哈哈', '6哈哈', '7哈哈']

Array.prototype.includes()


Array.prototype.includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。Array.prototype.includes() 判断两值相等的算法为sameValueZero算法。

注意

Array.prototype.indexOf()Array.prototype.includes() 在底层中判断两值相等的算法区别:

  • Array.prototype.indexOf()===算法一致

  • Array.prototype.includes()sameValueZero算法

语法

arr.includes(valueToFind[, fromIndex])
  • valueToFind: 需要查找的元素值。

  • fromIndex: 从fromIndex索引处开始查找valueToFind

    • fromIndex >= 数组长度,直接返回false
    • 0 <= fromIndex < 数组长度 ,从fromIndex处开始搜索
    • fromIndex < 0,计算数组长度 + fromIndex的值
      • 如果计算出的值小于0,从索引值为0的位置开始搜索
      • 如果计算出的值大于0, 从计算出的位置处开始搜索

返回值

返回一个布尔值 Boolean 。

对比

  • Array.prototype.includes()Array.prototype.indexOf() 有什么区别?

    • indexOf 比较两个值的时候只使用了===,所以NaN不可以检测

    • includes 比较两个值的时候内部使用了sameValueZero算法 即x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) 可以检测到NaN

    const array = [NaN];

    console.log(array.indexOf(NaN)); // -1
    console.log(array.includes(NaN)); // true

应用场景

原理(Polyfill)

Array.prototype.includes = function(valueToFind,fromIndex){
if(this == null){
throw new TypeError('this is null or not defined');
}
var object = Object(this);
var length = object.length >>> 0;
var fromIndexCopy = fromIndex >> 0;
if(fromIndexCopy > length){
return false;
}
function sameValueZero(x,y){
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y))
}
var index = Math.max(fromIndexCopy>=0?fromIndexCopy:length+fromIndexCopy,0);
while(index < length){
var value = object[index];
if(sameValueZero(value,valueToFind)){
return true;
}
index++;
}
return false;
}

const array1 = [1,2,3,4,5];
console.log(array1.includes(3)); // true
const array2 = [1,2,3,4,5];
console.log(array2.includes(3,3)); // false
const array3 = [1,2,3,4,5];
console.log(array3.includes(3,-3)); // true

Array.prototype.indexOf()


Array.prototype.indexOf() 返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1Array.prototype.indexOf() 判断两值相等的算法同===

注意

Array.prototype.indexOf()Array.prototype.includes() 在底层中判断两值相等的算法区别:

  • Array.prototype.indexOf()===算法一致

  • Array.prototype.includes()sameValueZero算法

语法

arr.indexOf(searchElement[, fromIndex])
  • searchElement: 要查找的元素

  • fromIndex: 开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-1表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.

返回值

首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1

对比

  • Array.prototype.includes()Array.prototype.indexOf() 有什么区别?

    • indexOf 比较两个值的时候只使用了===,所以NaN不可以检测

    • includes 比较两个值的时候内部使用了sameValueZero算法 即x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)) 可以检测到NaN

    const array = [NaN];

    console.log(array.indexOf(NaN)); // -1
    console.log(array.includes(NaN)); // true

应用场景

  • 场景一、通过indexOf查找NaN: indexOf 通过===全等判断两值是否先等,NaN !== NaN ,所以返回 -1

    const array = [1,2,NaN,3,NaN,4,NaN];
    console.log(array.indexOf(NaN)); // -1
    console.log(array.includes(NaN)); // true

原理

Array.prototype.indexOf = function(valueToFind,fromIndex){
if(this == null){
throw new TypeError('this is null or not defined');
}
var object = Object(this);
var length = object.length >>> 0;
var fromIndexCopy = fromIndex >> 0;
var index = Math.max(fromIndexCopy >= 0 ? fromIndexCopy : length + fromIndexCopy,0);
while(index < length){
if(index in object){
var value = object[index];
if(value === valueToFind){
return index;
}
}
index++;
}
return -1;
}

const array = [1,2,3,4,5,6,7,8];
console.log(array.indexOf(4,2)); // true
console.log(array.indexOf(4,-2)); // false

Array.isArray()


**Array.isArray()**用于确定传递的值是否是一个 Array。

语法

Array.isArray(obj)
  • obj: 需要检测的值。

返回值

如果值是 Array,则为true; 否则为false。

应用

原理

Array.isArray = function(array){
return Object.prototype.toString.call(array) === '[object Array]';
}

Array.prototype.join()


Array.prototype.join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。如果一个元素为 undefined 或 null,它会被转换为空字符串

语法

arr.join([separator])
  • separator: 指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,)分隔。如果separator是空字符串(""),则所有元素之间都没有任何字符。

返回值

一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。

应用

  • 将一个数组连接成字符串:

    1. 一个元素为 undefined 或 null,它会被转换为空字符串;
    2. 默认分隔符为 ,,
    3. 如果分隔符为空字符串,则中间没有任何字符
    const array = ['柏',undefined,'拉',null,'图'];
    console.log(array.join()); // 柏,,拉,,图
    console.log(array.join('-')); // 柏--拉--图
    console.log(array.join('')); // 柏拉图

原理

Array.prototype.keys()


Array.prototype.keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。

语法

arr.keys()

返回值

一个新的 Array 迭代器对象。

应用

原理

Array.prototype.lastIndexOf()


Array.prototype.lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。Array.prototype.lastIndexOf() 判断两值相等的算法同===

注意

Array.prototype.indexOf()Array.prototype.includes 以及 **Array.prototype.lastIndexOf()**在底层中判断两值相等的算法区别:

  • Array.prototype.includes 为sameValueZero算法
  • Array.prototype.indexOf() 同 Array.prototype.lastIndexOf() 与===算法一致

语法

arr.lastIndexOf(searchElement[, fromIndex])
  • searchElement: 被查找的元素
  • fromIndex: 从此位置开始逆向查找。默认为数组的长度减 1(arr.length - 1),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找

返回值

数组中该元素最后一次出现的索引,如未找到返回-1

Array.of()


Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

注意

Array.of()Array() 的区别?

  • Array.of(7) 创建一个具有单个元素 7 的数组
  • Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

语法

Array.of(element0[, element1[, ...[, elementN]]])
  • elementN: 任意个参数,将按顺序成为返回数组中的元素。

返回值

新的 Array 实例。

应用

  • 创建元素为1,2,3的数组

    const array = Array.of(1,2,3);
    console.log(array); // [1, 2, 3]

原理

Array.of = function(){
return Array.prototype.slice.call(arguments);
}
const array = Array.of(1,2,3);
console.log(array); // [1, 2, 3]

Array.prototype.pop()


**Array.prototype.pop()**方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。

语法

arr.pop()

返回值

从数组中删除的元素(当数组为空时返回undefined)。

应用

  • 空数组调用pop()方法: 空数组上调用 pop(),它返回 undefined。

    const result = [].pop();
    console.log(result); // undefined
  • 删除数组的最后一个元素-出栈

    const array = [1,2,3,4];
    const result = array.pop();
    console.log(result); // 4
    console.log(array); // [1, 2, 3]

Array.prototype.push()


Array.prototype.push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

语法

arr.push(element1, ..., elementN)
  • elementN: 被添加到数组末尾的元素。

返回值

当调用该方法时,新的 length 属性值将被返回。

应用

  • 添加元素到数组中去-进栈

    const array = [1,2,3,4];
    const result = array.push(5);
    console.log(result); // 5 注意这里的 5 是数组长度
    console.log(array); //  [1, 2, 3, 4, 5]

原理

Array.prototype.reduce()


Array.prototype.reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。Array.prototype.reduce() 逐个遍历数组元素,每一步都将当前元素的值与上一步的计算结果相加(上一步的计算结果是当前元素之前所有元素的总和)——直到没有更多的元素被相加。

语法

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback: 执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数:
    • accumulator: 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。
    • currentValue: 数组中正在处理的元素。
    • index 可选: 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。
    • array可选: 调用reduce()的数组
  • initialValue可选: 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

返回值

使用 “reducer” 回调函数遍历整个数组后的结果。

应用

  • reduced对未初始化的元素不进行任何操作

    const array = [1,2,3,4,,,,5,6,7,8];
    const result2 = array.reduce(function(accumulator,currentValue,index,arr){
    console.log(currentValue); //1 2 3 4 5 6 7 8
    return accumulator+currentValue; // 38
    },2);
    console.log(result2);
  • 数组里所有值的和

    const array = [1,3,5,7,9];
    const result = array.reduce(function(accumulator,currentValue,index,arr){
    return accumulator+currentValue;
    },0);
    console.log(result);
  • 累加对象数组里的值

    const array = [{title:'手机',price:6300},{title:'电脑',price:480}];
    const result = array.reduce(function(accumulator,currentValue,index,arr){
    return accumulator+currentValue.price;
    },0);
    console.log(result);
  • 将二维数组转化为一维

    const array =  [[0, 1], [2, 3], [4, 5]];
    const result = array.reduce(function(accumulator,currentValue,index,arr){
    return accumulator.concat(currentValue);
    },[]);
    console.log(result);
  • 计算数组中每个元素出现的次数

    const array =  [1,1,3,3,3,3,3,6,7,7,7,7,7,8,8,8,8];
    const result = array.reduce(function(accumulator,currentValue,index,arr){
    if(currentValue in accumulator){
    accumulator[currentValue]++
    }else{
    accumulator[currentValue] = 1;
    }
    return accumulator;
    },{});
    console.log(result);
  • 按属性对object分类

    function groupBy(objectArray,property){
    return objectArray.reduce(function(accumulator,currentValue,index,arr){
    const key = currentValue[property];
    if(!accumulator[key]){
    accumulator[key] = [];
    }
    accumulator[key].push(currentValue);
    return accumulator;
    },{});
    }
    const array = [
    { name: "Alice", age: 21 },
    { name: "Max", age: 20 },
    { name: "Jane", age: 20 },
    ];
    const result = groupBy(array,'age');
    console.log(result);
  • 使用reduce实现map

    Array.prototype.mapUsingReduce = function(callback,thisArg){
    return this.reduce(function(accumulator,currentValue,index,arr){
    accumulator[index] = callback.call(thisArg,currentValue,index,arr);
    return accumulator;
    },[]);
    }
    const result = [1,2,3].mapUsingReduce(function(currentValue,index,arr){
    return currentValue*2;
    });
    console.log(result);

原理(Polyfill)

Array.prototype.reduce = function(callback, initialValue){
if(this == null){
throw new TypeError('this is null or not defined');
}
if(typeof callback !== 'function'){
throw new TypeError('callback is not function');
}
var object = Object(this);
var length = object.length >>> 0;
var index = 0;
var result ;
if(initialValue !== undefined){
result = initialValue
}else{
while(index < length && !(index in object)){
index++;
}
if(index>=length){
throw new TypeError('array is empty with no initial value');
}
result = object[index++];
}
while(index < length){
if(index in object){
var value = object[index];
result = callback(result,value,index,object);
}
index++;
}
return result;
}


const array = [1,2,3,4,,,,5,6,7,8];
const result1 = array.reduce(function(accumulator,currentValue,index,arr){
console.log(currentValue);
return accumulator+currentValue;
});
console.log(result1);
const result2 = array.reduce(function(accumulator,currentValue,index,arr){
console.log(currentValue);
return accumulator+currentValue;
},2);
console.log(result2);

Array.prototype.reduceRight()


Array.prototype.reduceRight() 方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。

语法

arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback: 一个回调函数,用于操作数组中的每个元素,它可接受四个参数:
    • accumulator: 累加器:上一次调用回调函数时,回调函数返回的值。首次调用回调函数时,如果 initialValue 存在,累加器即为 initialValue,否则须为数组中的最后一个元素(详见下方 initialValue 处相关说明)
    • currentValue: 当前元素:当前被处理的元素。
    • index: 数组中当前被处理的元素的索引。
    • array: 调用 reduceRight() 的数组。
  • initialValue: 首次调用 callback 函数时,累加器 accumulator 的值。如果未提供该初始值,则将使用数组中的最后一个元素,并跳过该元素。如果不给出初始值,则需保证数组不为空。否则,在空数组上调用 reduce 或 reduceRight 且未提供初始值

返回值

执行之后的返回值。

应用

  • 通过reduceRight()实现组合函数: 组合函数是一个从右向左流动的函数,用上一个函数的输出调用每个函数。

    function compose(...funcArray){
    return function(args){
    return funcArray.reduceRight(function(accumulator,currentValue,index,arr){
    return currentValue(accumulator);
    },args);
    }
    }

    function fun1(n){
    return n+1;
    }
    function fun2(n){
    return n*2;
    }
    const accumulator = compose(fun2,fun1);
    const result = accumulator(8);
    console.log(result);

原理(Polyfill)

Array.prototype.reduceRight = function(callback,initialValue){
if(this == null){
throw new TypeError('this is null or not defined');
}
if(typeof callback !== 'function'){
throw new TypeError('callback is not function');
}
var object = Object(this);
var length = object.length >>> 0;
var index = length-1;
var result;
if(initialValue !== undefined){
result = initialValue;
}else{
while(index > -1 && !(index in object)){
index--;
}
if(index < 0){
throw new TypeError('array is empty with no initial value');
}
result = object[index--];
}
while(index > -1){
if(index in object){
var value = object[index];
result = callback(result,value,index,object);
}
index--;
}
return result;
}

const arr = [1,2,3,,,,,4,6,7];
const result = arr.reduceRight(function(accumulator,currentValue,index){
console.log(currentValue);
return accumulator + currentValue;
},0);
console.log(result);

Array.prototype.reverse()


**Array.prototype.reverse()**方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

语法

arr.reverse()

返回值

颠倒后的数组。

应用

  • 颠倒数组

    const array = [1,2,3,4,5,6];
    console.log(array.reverse()); // [6, 5, 4, 3, 2, 1]

原理

Array.prototype.shift()


Array.prototype.shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

语法

arr.shift()

返回值

从数组中删除的元素; 如果数组为空则返回undefined 。

应用

  • 移除数组中的第一个元素-出队列

    const array = [1,2,3,4,5,6];
    console.log(array.shift()); // 1
    console.log(array); //  [2, 3, 4, 5, 6]

原理

Array.prototype.slice()


Array.prototype.slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

语法

arr.slice([begin[, end]])
  • begin 可选: 提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。如果省略 begin,则 slice 从索引 0 开始。如果 begin 超出原数组的索引范围,则会返回空数组。
  • end 可选: 提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。slice 会提取原数组中索引从 begin 到 end 的所有元素(包含 begin,但不包含 end)。slice(1,4) 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。如果 end 被省略,则 slice 会一直提取到原数组末尾。如果 end 大于数组的长度,slice 也会一直提取到原数组末尾。

返回值

一个含有被提取元素的新数组。

应用

  • 拷贝数组

    const array = [1,2,3,4];
    const arrayCopy = array.slice();
    console.log(arrayCopy); // [1, 2, 3, 4]
  • 转换类数组对象

    function createArrayLike(){
    return arguments;
    }
    const array = Array.prototype.slice.call(createArrayLike(1,2,3,4,5));
    console.log(array); //  [1, 2, 3, 4, 5]

原理

Array.prototype.some()


Array.prototype.some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。如果用一个空数组进行测试,在任何情况下它返回的都是false。

危险

[].some()[].every() 的区别:

  • [].some() 无论如何都会返回false
  • [].every() 无论如何都会返回true

语法

arr.some(callback(element[, index[, array]])[, thisArg])
  • callback: 用来测试每个元素的函数,接受三个参数:
    • element: 数组中正在处理的元素。
    • index 可选: 数组中正在处理的元素的索引值。
    • array可选: some()被调用的数组。
  • thisArg可选: 执行 callback 时使用的 this 值。

返回值

数组中有至少一个元素通过回调函数的测试就会返回true;所有元素都没有通过回调函数的测试返回值才会为false。

应用

  • 通过some()检测空数组: [].some() 无论回调函数是怎样的,都会返回 false 的

    const array = [];
    console.log(array.some(function(value,index,arr){
    return value<10
    })); // false
  • 通过some检测数组中是否有一个小于10的数

    const array = [10,20,30,40,5];
    console.log(array.some(function(value,index,arr){
    return value<10
    })); // true

原理(Polyfill)

Array.prototype.some = function(callback,thisArg){
if(this == null){
throw new TypeError('this is null or not defined');
}
if(typeof callback !== 'function'){
throw new TypeError('callback is not function');
}
var object = Object(this);
var length = object.length >>> 0;
var index = 0;
while(index < length){
if(index in object){
var value = object[index];
var result = callback.call(thisArg,value,index,object);
if(result){
return true;
}
}
}
return false;
}
const array = [];
console.log(array.some(function(value,index,arr){
return value<10
})); // true

Array.prototype.sort()


Array.prototype.sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。

语法

arr.sort([compareFunction])
  • compareFunction 可选: 用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。

    • firstEl: 第一个用于比较的元素。
    • secondEl: 第二个用于比较的元素。
  • 对于compareFunction(firstEl,secondEl)

    • 如果compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
    • 如果compareFunction(a, b) 等于 0, a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
    • 如果compareFunction(a, b) 大于 0, b 会被排列到 a 之前。
    array.sort(function(firstEl,secondEl){
    if(firstEl<secondEl){
    return -1;
    }
    if(firstEl>secondEl){
    return 1;
    }
    return 0;
    });

    // 可以简写为:

    array.sort(function(firstEl,secondEl){
    return firstEl - secondEl;
    });

返回值

排序后的数组。请注意,数组已原地排序,并且不进行复制。

应用

  • 将数组升序排序

    const array = [2,7,1,9,10,3,20,5,5];
    array.sort(function(a,b){
    return a-b;
    });
    console.log(array);
  • 对非 ASCII 字符排序

    var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
    items.sort(function (a, b) {
    return a.localeCompare(b);
    });

    // items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']

原理

Array.prototype.splice()


Array.prototype.splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

语法

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • start: 指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
  • deleteCount: 整数,表示要移除的数组元素的个数。如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。如果 deleteCount 被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
  • item1,item2……: 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。

返回值

由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

应用

  • 指定位置删除元素

    array.slice(index,1); 
  • 指定位置插入元素

    array.slice(index,0,新增的元素值);
  • 指定位置替换元素

    array.slice(index,1,新增的元素值);

原理

Array.prototype.toLocaleString()


Array.prototype.toLocaleString() 返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ",")隔开。

语法

arr.toLocaleString([locales[,options]]);
  • locales: 带有BCP 47语言标记的字符串或字符串数组,关于locales参数的形式与解释,请看Intl页面。
  • options: 一个可配置属性的对象

返回值

表示数组元素的字符串。

应用

原理

Array.prototype.toString()


Array.prototype.toString() 返回一个字符串,表示指定的数组及其元素。

注意

Array 对象覆盖了 ObjecttoString 方法。对于数组对象,toString 方法在内部调用 join() 方法拼接数组中的元素并返回一个字符串,其中包含用逗号分隔的每个数组元素。如果 join 方法不可用,或者它不是一个函数,将使用 Object.prototype.toString 代替,返回 [object Array]

语法

const arr = [1, 2];
console.log(arr.toString()); // 1,2
console.log(typeof arr.toString()); // string
console.log(arr.toString() === arr); // false

返回值

一个表示数组所有元素的字符串。

应用

原理(Polyfill)

Array.prototype.toString = function(){
if(this.join && typeof this.join === "function"){
return this.join(",");
}
return Object.prototype.toString.call(this);
}

const arr = [1,2];
console.log(arr.toString())

Array.prototype.unshift()


Array.prototype.unshift() 将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。

语法

arr.unshift(element1, ..., elementN)
  • elementN: 要添加到数组开头的元素或多个元素。

返回值

当一个对象调用该方法时,返回其 length 属性值。

应用

原理

Array.prototype.values()


Array.prototype.values() 返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值

语法

arr.values()

返回值

一个新的 Array 迭代对象。

应用

原理

问题


问题一、Objet(this) 的作用

Objet(this)的作用: 去除多余的,

如果数组为 [1,,,,,,4,,,,,,5] ,那么通过 Object(this) 会自动去除 , 后续通过 index in object 即可判断非 , 元素

问题二、sameValueZero 算法

function sameValueZero(x,y){
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y))
}

问题三、object.length >>> 0 无符号位右移的作用

object.length >>> 0 无符号位右移的作用: 将其他非 number 类型转化为 number 类型 0

console.log(
Object("str"),
Object("str").length,
Object("str").length >> 0,
Object("str").length >>> 0
); // String {'str'} 3 3 3
console.log(
Object(2),
Object(2).length,
Object(2).length >> 0,
Object(2).length >>> 0
); // Number {2} undefined 0 0
console.log(
Object([2, 3]),
Object([2, 3]).length,
Object([2, 3]).length >> 0,
Object([2, 3]).length >>> 0
); // (2) [2, 3] 2 2 2
console.log(
Object([2, 3]),
Object([2, 3]).length,
Object([2, 3]).length >> 0,
Object([2, 3]).length >>> 0
); //  [2, 3] 2 2 2
console.log(
Object(null),
Object(null).length,
Object(null).length >> 0,
Object(null).length >>> 0
); // {} undefined 0 0
console.log(
Object(undefined),
Object(undefined).length,
Object(undefined).length >> 0,
Object(undefined).length >>> 0
); // {} undefined 0 0
console.log(
Object(true),
Object(true).length,
Object(true).length >> 0,
Object(true).length >>> 0
); // Boolean {true} undefined 0 0
console.log(
Object(function(){}),
Object(function(){}).length,
Object(function(){}).length >> 0,
Object(function(){}).length >>> 0
); // ƒ (){} 0 0 0

问题四、start >> 0 有符号位右移的作用

start >> 0 有符号位右移的作用 : 将其他非 number 类型转化为 number 类型 0,并且将数值类型向下取整

console.log(
Object("str"),
Object("str").length,
Object("str").length >> 0,
Object("str").length >>> 0
); // String {'str'} 3 3 3
console.log(
Object(2),
Object(2).length,
Object(2).length >> 0,
Object(2).length >>> 0
); // Number {2} undefined 0 0
console.log(
Object([2, 3]),
Object([2, 3]).length,
Object([2, 3]).length >> 0,
Object([2, 3]).length >>> 0
); // (2) [2, 3] 2 2 2
console.log(
Object([2, 3]),
Object([2, 3]).length,
Object([2, 3]).length >> 0,
Object([2, 3]).length >>> 0
); //  [2, 3] 2 2 2
console.log(
Object(null),
Object(null).length,
Object(null).length >> 0,
Object(null).length >>> 0
); // {} undefined 0 0
console.log(
Object(undefined),
Object(undefined).length,
Object(undefined).length >> 0,
Object(undefined).length >>> 0
); // {} undefined 0 0
console.log(
Object(true),
Object(true).length,
Object(true).length >> 0,
Object(true).length >>> 0
); // Boolean {true} undefined 0 0
console.log(
Object(function(){}),
Object(function(){}).length,
Object(function(){}).length >> 0,
Object(function(){}).length >>> 0
); // ƒ (){} 0 0 0

console.log(30>>0,30>>>0); // 30 30
console.log(30.5>>0,30.5>>>0); // 30 30
console.log(-30>>0,-30>>>0); // -30 4294967266
console.log(-30.5>>0,-30.5>>>0); // -30 4294967266

问题五、result = object[index++]的作用

result = object[index++]的作用: result的原则是如果没有设定初始值,那么 result取数组中第一个非占位的元素值,并且从下一个元素开始迭代循环。那么如何获取实现第一个非占位的元素值: 通过 Ojbect将数组包装成对象,通过in操作符来检测数组索引 in Object(数组),知道第一个符合条件的索引出现,并且从这个索引的下一个元素非占位元素开始循环迭代。

while(index < length && !(index in object)){
index++;
}
if(index >= length){
throw new TypeError('array is empty with no initial value');
}
result = object[index++]