2017-10-08 114 views
2

无法重现MDN's example(“以类似数组的方式使用对象”)。使用[] .push.call()修改对象的长度

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 

如果我们调用函数的一些不同agrument,不{},将它的工作?如果它不会,那么为什么我们应该完全使用{}?这里的this背景是什么:addEl方法还是对象本身?如果第二个,为什么不addEl函数:它不是一个数组函数,所以它应该有它自己的this(和,我想,我会使用像objThis = this;属性)。

另一个相关的问题是here

回答

3

在您的文章中的代码有一些错别字:

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 

如果我们调用函数的一些不同的观点,而不是{},将它的工作?

当然会。为什么不呢? JavaScript中的数组可以包含不同类型的值。 它不需要是同质的, 所以是的,你可以插入除{}以外的其他东西。

什么是this上下文这里:addEl方法或对象本身?

这是调用方法的对象。所以它是obj。 这是如何调用方法。 当您拨打obj.something()时,something内部的this将为obj


如果您仍然对此示例有疑问,请随时放下评论。

+0

也许这很愚蠢,但为什么这里不需要分号?我认为,这是每个声明都需要的(抛开一个事实,即JS引擎可以自己预测它们的位置)。 – JulyMorning

+1

@JulyMorning这不是一个声明,而是一个对象文字。一个类似的例子,你可能会看到更好的是'{a:1,b:2;}',这是不正确的,';'不应该在那里。在对象文字之后,要终止一个语句,你当然应该放一个分号,例如'var obj = {a:1,b:2};' – janos

+0

可以请你看一下我在编辑中的问题? – JulyMorning

2

由于对象不是数组,而是可以表现得像一个数组,所以您需要从Array对象中借用push

但是在这种情况下,this引用用简写形式[]创建的数组对象。因此,我们需要使用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);

+0

对于每种情况,“[]”是否缩短«Arryay.prototype»的适当方式?或者,对于每个呼叫/绑定功能,可能都是这样? – JulyMorning

+1

'[]'是'new Array()'的缩写。当你使用一个像对象一样的数组,像一个节点列表或者一个具有属性的对象时,你有时想在它们上使用数组函数。但是Object没有像forEach和push这样的函数。所以我们转向主对象'Array'并使用它的原型来借用它的功能。但是,如果我们只是'Array.prototype.push(element)',它会尝试将元素添加到Array主对象并失败。所以我们必须链接我们的对象,通过使用call或bind来传递它的引用。 – Mouser

1
var array = { 
    length: 0, 
    push: function(obj){ 
     this[this.length] = obj; 
     this.length++; 
    } 
} 

array.push(23); 

你可以试试这个,这能解决您的problrm我猜。