最近同事分享了一道题
let obj = {
2:3,
3:4,
length:2,
push:Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
obj是一个类数组,其中引入了Array原型链上的push方法,关键就是要搞清楚Array.prototype.push的方法定义。
经过查看资料,发现push的方法可以用js如下模拟:
Array.prototype.push = function(...items) {
let O = Object(this); // ecma 中提到的先转换为对象
let len = this.length >>> 0;
let argCount = items.length >>> 0;
// 2 ^ 53 - 1 为JS能表示的最大正整数
if (len + argCount > 2 ** 53 - 1) {
throw new TypeError("The number of array is over the max value")
}
for(let i = 0; i < argCount; i++) {
O[len + i] = items[i];
}
let newLength = len + argCount;
O.length = newLength;
return newLength;
}
push的参数可以是一个元素,或者多个逗号连接的元素。
在这道题中,
obj.push(1)相当于obj[obj.length] = 1,obj.length = obj.length+1;
obj.push(2)相当于obj[obj.length] = 2,obj.length = obj.length+1;
因此最后的结果是
console.log(obj)
{2:1,3:2,length:4,push:fn}
如果改成
let obj = {
2:3,
3:4,
length:2
}
Array.prototype.push.call(obj,1)
Array.prototype.push.call(obj,2)
console.log(obj)
结果是相同地,使用call将push方法借用给obj对象