使用 [].push.call() 修改对象的长度
Using [].push.call() to modify an object's length
无法重现 MDN's example(«以类似数组的方式使用对象»)。
let obj = {
length: 0,
addEl: function (element) {
[].push.call(this, element);
};
};
// Node REPL still expect me to do something, so there's an error. Why?
伙计们,你们能解释一下这里出了什么问题吗?另外,我似乎不明白这里的机制:
// from the example:
obj.addElem({});
obj.addElem({});
console.log(obj.length);
// → 2
如果我们用一些不同的参数调用函数,而不是 {}
,它会工作吗?如果它不会,那我们为什么要使用 {}
呢?这里的 this
上下文是什么:addEl
方法或对象本身?如果是第二个,为什么不用 addEl
函数:它不是数组函数,所以它应该有自己的 this
(而且,我想,我会使用类似 objThis = this;
属性).
另一个相关问题是 。
您 post 中的代码有一些拼写错误:
let obj = {
length: 0,
addEl: function (element) {
[].push.call(this, element);
};
^ syntax error
};
// Node REPL still expect me to do something, so there's an error. Why?
正如您在代码注释中所怀疑的那样,
有一个语法错误,我已为您标记。
删除那个分号。
然后,在尝试您编写的示例时 obj.addElem
,
但是在上面的对象文字中你有 addEl
.
如果您只是复制粘贴该示例,该示例应该可以正常工作。
var obj = {
length: 0,
addElem: function addElem(elem) {
// obj.length is automatically incremented
// every time an element is added.
[].push.call(this, elem);
}
};
// Let's add some empty objects just to illustrate.
obj.addElem({});
obj.addElem({});
console.log(obj.length);
// → 2
What if we call the function with some different argument, not {}
, will it work?
当然会。为什么不呢? JavaScript 中的数组可以包含不同类型的值。
它不需要是同质的,
所以是的,您可以插入除 {}
.
以外的其他内容
What is the this
context here: addEl
method or the object itself?
这是调用方法的对象。所以是obj
。
这就是方法调用的工作原理。
当您调用 obj.something()
时,something
中的 this
将是 obj
.
如果您对此示例仍有疑问,请随时发表评论。
由于对象不是数组,但可以像数组一样工作,因此您需要从 Array
对象借用 push
。
但在这种情况下 this
指的是用 shorthand []
创建的数组对象。所以我们需要使用 call
.
将其更改为 obj
的范围
因为有length
属性定义,push会更新这个值
空对象作为元素传递 {}
,但任何其他元素都可以:
let obj = {
length: 0,
addEl: function(element) {
Array.prototype.push.call(this, element); //also borrowing push from the array.prototype prevents an extra array to be made in memory every time we call upon this function.
} //« fixed the typo here
};
obj.addEl({});
obj.addEl(1);
obj.addEl('a');
obj.addEl(true);
console.log(obj);
var array = {
length: 0,
push: function(obj){
this[this.length] = obj;
this.length++;
}
}
array.push(23);
你可以试试这个,我想这解决了你的问题。
无法重现 MDN's example(«以类似数组的方式使用对象»)。
let obj = {
length: 0,
addEl: function (element) {
[].push.call(this, element);
};
};
// Node REPL still expect me to do something, so there's an error. Why?
伙计们,你们能解释一下这里出了什么问题吗?另外,我似乎不明白这里的机制:
// from the example:
obj.addElem({});
obj.addElem({});
console.log(obj.length);
// → 2
如果我们用一些不同的参数调用函数,而不是 {}
,它会工作吗?如果它不会,那我们为什么要使用 {}
呢?这里的 this
上下文是什么:addEl
方法或对象本身?如果是第二个,为什么不用 addEl
函数:它不是数组函数,所以它应该有自己的 this
(而且,我想,我会使用类似 objThis = this;
属性).
另一个相关问题是
您 post 中的代码有一些拼写错误:
let obj = {
length: 0,
addEl: function (element) {
[].push.call(this, element);
};
^ syntax error
};
// Node REPL still expect me to do something, so there's an error. Why?
正如您在代码注释中所怀疑的那样, 有一个语法错误,我已为您标记。 删除那个分号。
然后,在尝试您编写的示例时 obj.addElem
,
但是在上面的对象文字中你有 addEl
.
如果您只是复制粘贴该示例,该示例应该可以正常工作。
var obj = { length: 0, addElem: function addElem(elem) { // obj.length is automatically incremented // every time an element is added. [].push.call(this, elem); } }; // Let's add some empty objects just to illustrate. obj.addElem({}); obj.addElem({}); console.log(obj.length); // → 2
What if we call the function with some different argument, not
{}
, will it work?
当然会。为什么不呢? JavaScript 中的数组可以包含不同类型的值。
它不需要是同质的,
所以是的,您可以插入除 {}
.
What is the
this
context here:addEl
method or the object itself?
这是调用方法的对象。所以是obj
。
这就是方法调用的工作原理。
当您调用 obj.something()
时,something
中的 this
将是 obj
.
如果您对此示例仍有疑问,请随时发表评论。
由于对象不是数组,但可以像数组一样工作,因此您需要从 Array
对象借用 push
。
但在这种情况下 this
指的是用 shorthand []
创建的数组对象。所以我们需要使用 call
.
obj
的范围
因为有length
属性定义,push会更新这个值
空对象作为元素传递 {}
,但任何其他元素都可以:
let obj = {
length: 0,
addEl: function(element) {
Array.prototype.push.call(this, element); //also borrowing push from the array.prototype prevents an extra array to be made in memory every time we call upon this function.
} //« fixed the typo here
};
obj.addEl({});
obj.addEl(1);
obj.addEl('a');
obj.addEl(true);
console.log(obj);
var array = {
length: 0,
push: function(obj){
this[this.length] = obj;
this.length++;
}
}
array.push(23);
你可以试试这个,我想这解决了你的问题。