我掙扎着一個我以前認爲我理解的主題 - JavaScript中的原型繼承。JavaScript原型繼承混淆 - 我在這裏錯過了什麼?
我有我的概括問題here
我有一個基本對象和繼承實施的jsfiddle。我希望實現更改基本屬性,並讓基礎訪問這些更新的屬性。
任何人都可以請指出我要去哪裏錯了嗎?
我掙扎着一個我以前認爲我理解的主題 - JavaScript中的原型繼承。JavaScript原型繼承混淆 - 我在這裏錯過了什麼?
我有我的概括問題here
我有一個基本對象和繼承實施的jsfiddle。我希望實現更改基本屬性,並讓基礎訪問這些更新的屬性。
任何人都可以請指出我要去哪裏錯了嗎?
當你調用new cheeseBase()
的的this
值是您正在使用爲原型來自內部「切達()」的對象,而不是「切達」的實例。因此,「saySomething()」函數總是說「全部奶酪」,因爲它指的是構造函數調用中的「捕獲」this
。
如果您在「alert()」調用中更改「saySomething()」以引用「this.favoriteCheese」,它會在彈出窗口中顯示「cheddar」。
如果你真的想子類進行修改的基本對象,或者,你可以重新排列:
function cheesebase() {
var that = this;
this.favouriteCheese = "all cheese";
this.setBaseCheese = function(chz) {
that.favouriteCheese = chz;
};
this.saySomething = function() {
alert("My favourite cheese is " + that.favouriteCheese);
};
}
function cheddar() {
var returnObject = Object.create(new cheesebase());
returnObject.setBaseCheese("cheddar");
returnObject.saySomethingElse = function() {
alert("I like cheese");
};
return returnObject;
}
我非常感謝您的意見。有沒有這種情況下,我會用'this'遇到麻煩?我知道它基於上下文而改變。如果我沒有使用任何關閉,我會好嗎? - 根據你原來的帖子,沒有'setCheeseBase'函數 – tomfumb
2 tomfumb,你可能會遇到用戶界面回調的麻煩,通常是 $('#btn')。click(obj.saySomething);會將此綁定更改爲單擊元素的上下文。 –
如果你接受我的第一個建議(在「saySomething()」中將「that」改爲「this」),那麼對該函數的調用將把this設置爲該類的* instance *。這意味着每個實例都將擁有自己的「favouriteCheese」屬性。這應該可以正常工作,但是您的問題指出,您希望**實例設置基類屬性。我不知道爲什麼,因爲它看起來像奶酪,因此會互相對抗,而奶酪的鬥爭是一個可怕的前景:-) – Pointy
也許你想達到什麼是這樣的:http://jsfiddle.net/yrU6y/1/
不管怎樣,在你原來的例子你沒有使用基礎對象的原型。這意味着,每次創建新的cheesebase
時,都會重新定義其功能,即每個cheesebase
對象都有自己的功能,而不是共享原型(並使用更少的內存)。
謝謝,雖然jsfiddle是原來的一樣... – tomfumb
對不起,它是http://jsfiddle.net/yrU6y/1/固定。 –
我最好猜測,下面的代碼會導致問題。
var that = this;
我的原始直覺(不參考JS規範),重要的是原型基於繼承是基於原型對象的單個實例,如果沒有這種對象的複印。 那麼,this
指針裏面cheeseBase
指向原型對象,應該永遠不會改變。
後代方法和屬性綁定,在尋找方法或屬性時遍歷[this,this.prototype,this.prototype.prototype,...]序列,其中每個原型都意味着不可變的單例對象。
鑑於此,cheeseBase
構造有this
指向實際原型,將其存儲裏面的指針that
和周圍that
創建關閉,這是原型對象。
而且,在cheeseBase
的綁定執行過程中this
的綁定更改爲實際對象實例。
我想這樣的事情,可以在JS規範中的這個綁定下找到。
+1提供js小提琴。 –