2017-10-08 117 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我猜。