我正在尝试将一些结构放到我的JavaScript代码中,并希望将一些原型函数添加到命名空间中,如下所示:
Person.drink();
Person.eat.steak();
我尝试过类似的东西,但它没有按预期工作:
var Person = function() {
this.thirsty = true;
this.hungry = true;
this.drink();
this.eat.steak();
}
Person.prototype.drink = function() {
this.thirsty = false;
}
Person.prototype.eat = {
steak: function() {
this.hungry = false;
}
};
var me = new Person();
console.log(me.thirsty, me.hungry);
控制台输出:false, true
(小提琴:http://jsfiddle.net/upwz4u32/2/)
为什么我的嵌套/命名空间函数无法访问它的实例变量?
答案 0 :(得分:1)
而不是
this.eat.steak();
使用
this.eat.steak.call(this);
正如@lordvlad所说,在你的代码中,这是指原型的eat对象。
无论如何,将eat定义为原型定义方法本身的对象在我的意见中是很奇怪的。
为什么不去寻找类似的东西:
Person.prototype = {
eat: function(meat) {
switch (meat) {
case "steak":
this.hungry = false;
break;
// ...
}
},
// drink :
}
答案 1 :(得分:1)
为什么我的嵌套/命名空间函数无法访问它的实例变量?
因为当您执行me.eat.steak()
时,this
来电中的steak
为eat
,而不是me
。
如果您要通过call
this
内的编写属性,基本上无法在ES5中执行您之前和之前未使用steak
的操作}}。如果您只是读取它们,可以通过使eat
成为原型为Person
实例的对象来实现。
在ES6中,您可以通过将eat
一个Proxy
对象包裹在person实例中来实现,但此时它已经真正进行了错综复杂。
相反,要么使eat
成为真实对象,然后在必要时写回Person
,或者只使用命名约定(例如me.eat$steak()
)。