你基本上是正確的,但堆棧空間和繼承是兩個不同的問題,並在高層次的腳本語言,像JS垃圾回收是如何工作的可能是前途未卜。確實,單行代碼行的中間值會在該行完成後被銷燬。
此外,String.prototype.constructor
,簡直是本身一樣String
。 String
的任何「實例」將收到.__proto__
引用,該引用將指向String.prototype
,從而創建繼承鏈。如果發現對象屬性未被定義爲對象x
本身,則JavaScript自動首先檢查由x.__proto__
引用的對象,然後x.__proto__.__proto__
,一直到大多數情況下 - Object.prototype
。
請記住,__proto__
被JavaScript解釋器之間不同的方式實現,而不應被手動操作。很高興知道這樣的參考可以解釋原型魔法,但是沒有任何情況下你應該直接改變對象的參考。相反,您應該通過new
運算符或Object.create
來創建類的實例。在JavaScript中一個完整的超/子關係是這樣的:
function Animal(name, weight){
this.name = name, this.weight = weight;
this.alive = true;
this.hungry = true;
}
// At this point you could put in Animal.prototype = Object.create(Object.prototype); but JavaScript will set it automatically, so it’s unnecessary
Animal.prototype.kill = function(){
this.alive = false;
}
Animal.prototype.feed = function(){
this.hungry = false;
}
function Cat(name, weight){
Animal.call(this, name, weight);
this.lives = 9;
}
// Sometimes people instance a new parent like
// Cat.prototype = new Animal('doesntmatter', 420);
// The result is the same except that using Object.create saves the overhead
// of running a full constructor for an object that doesn’t need it
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.kill = function(){
this.lives--;
if(this.lives <= 0) this.alive = false;
};
var a = new Animal();
var c = new Cat();
/* a.feed and b.feed now reference the same function object,
but c.kill has been overridden since its prototype `__proto__` chain first
visits Cat.prototype, then Animal.prototype, then Object.prototype. */
最後,ES6引入了class
關鍵字是語法糖爲這個系統,並抽象構造函數的init
方法。