输出以下代码的执行结果,并加以解释。
1 | var obj = { |
一、数组 VS 类数组(Array-like)对象
在 JavaScript 中,数组就是由 Array 构造出来的对象。区分方式:判断其原型链是否指向 Array.prototype(push、pop、shift和join)。
二、Array.prototype.push
MDN解释为:
push()
方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。同时push
是特意设计为通用的。
push()
根据 length
属性决定从哪里开始插入给定的值。如果 length
不能被转成一个数值,则插入的元素索引为 0,包括 length
不存在时。当 length
不存在时,将会创建它。
三、问题回归
当一个对象调用 push()
时,对象的 length
属性和插入元素会发生变化。
因此 obj 返回结果为:1
2
3
4
5
6
7Object {
'2': 1,
'3': 2,
'length': 4,
'splice': Array.prototype.splice,
'push': Array.prototype.push,
}
但是当一个对象存在 length
和 splice
时,输出会被转换为一个伪数组。因此最终结果会变为:
1 | Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ] |
变形题:1
2
3
4
5
6var obj = {
'splice': Array.prototype.splice,
'push': Array.prototype.push,
};
obj.push(1);
console.log(obj); // Object [1, splice: ƒ, push: ƒ] obj.length -> 1
1 | var obj = { |
四、伪数组打印
当一个对象的 length
属性为数字,同时splice
属性为函数时, 对象的函数输出结果就会变成 伪数组。
1 | var obj1 = { |
在 DevTools,就是通过这些来进行判断对象是否为类数组。
1 | function isArrayLike(obj) { |
五、相关讨论
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/76
六、对象转数组
Array.from()
方法从一个类似数组或可迭代对象中创建一个新的数组实例。Array.prottype.slice.call(arguments)
生成新数组