2017-09-18 39 views
0

我写下了我在几句话中学到的内容,真正理解原型和对象包装器如何工作。如果我错了,请纠正我,如果我错过了其他详细信息,请告诉我。原型和对象包装器如何在JavaScript中工作?

JavaScript使用原型找上对象的方法和属性。例如,如果你创建一个字符串"Hello"这是一种原始的字符串值,并尝试应用该方法split()它("Hello".split()),字符串值强制转换为String对象,所以我们可以应用split()方法。该String对象由String.prototype.constructor创建。创建后,JavaScript将在原型对象中查找split()方法。在应用该方法并返回该值之后,不再需要String对象,因此它被牺牲给垃圾收集之神。

回答

2

你基本上是正确的,但堆栈空间和继承是两个不同的问题,并在高层次的脚本语言,像JS垃圾回收是如何工作的可能是前途未卜。确实,单行代码行的中间值会在该行完成后被销毁。

此外,String.prototype.constructor,简直是本身一样StringString的任何“实例”将收到.__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方法。

相关问题