tl; dr:在Field或Level.prototype对象中都没有字段cellsObserver。在Javascript中不存在经典的“自我”。
长话短说。
当你试图获取object.property
,JavaScript的看对象试图找到property
,然后到object.prototype
(这是另一个对象),依此类推,直到到达空原型在Object.prototype
参考。
所以,当你在等级构造函数调用第二次this.cellsObserver
,它是这样的: this
是一个公正的新构造的对象(如果它与new
关键字调用),并有cellsObserver
在属性列表,因此无需深入查找即可获取。
然后,
Field.prototype = Object.create(Level.prototype);
这仅意味着Field.prototype
现在将参照一个新的对象,其属性是相同的,在那一刻Level.prototype
。 从您的代码中,Level.prototype
对象中没有非标准属性(您没有提供任何)。
然后,
self = this;
在这里,你只是分配一个名为self
到刚刚创建的对象或窗口对象(it depends)的参考全局变量。如果您希望存储对this
对象的引用,则应该使用var
:var self = this
。但是你应该记住,这个self
变量只能在声明的范围或闭包中被访问。
然后,
所有的
Field.prototype = {
init: function() {
console.log('co from field ' + self.cellsObserver);
}
}
首先,在这里你只覆盖previos指令(Field.prototype = Object.create(Level.prototype);
)。 Field.prototype.init = function(){...}
:如果你想延长Field.prototype
对象,你可以在电话Object.create
in second argument,或只是通过访问一个这样的属性来完成。
二。当init
函数将被执行时,self
变量可能包含任何内容。只需在此使用this
作为当前对象。
三。让我们尝试猜测函数中this.cellsObserver
得到评估时会发生什么。
的this
对象参照Field
实例,并且不存在cellsObserver
属性那里,所以我们移动到Field.prototype
对象,这是上述({ init: function() {...}}
)中所定义,没有cellsObserver
任一,所以我们移动到Object.prototype
对象,这是null
。好的,我们的查找失败,this.cellsObserver
未定义。
将它会是什么样的Field.prototype = Object.create(Level.prototype)
不被下面的代码重写? this
对象将尽早引用Field实例。该Field.prototype指的是这是Level.prototype
对象的复制对象,有或者没有cellsObserver
这里。所以,我们期待Object.prototype
,就是这样。有一个在任何物体没有cellsObserver
除了在水平一流,这是不是在Field
情况下,任何方式引用的实例。将此代码粘贴http://www.objectplayground.com/:
你可以在这里玩
var Level = function() {
this.cellsObserver = new CellsObserver();
this.fieldObj = new Field();
}
var Field = function() {
this.init();
};
Field.prototype = Object.create(Level.prototype);
Field.prototype.init = function() {};
this.field = new Field();
这是相当明显的,你不明白prototypial继承(和其他一些JavaScript的概念)。我建议你阅读一些教程。 – Amit