你基本上是正确的,但堆栈空间和继承是两个不同的问题,并在高层次的脚本语言,像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
方法。