如何命名原型函数?

时间:2015-09-11 13:53:05

标签: javascript

我正在尝试将一些结构放到我的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/

为什么我的嵌套/命名空间函数无法访问它的实例变量?

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来电中的steakeat,而不是me

如果您要通过call this内的编写属性,基本上无法在ES5中执行您之前和之前未使用steak的操作}}。如果您只是读取它们,可以通过使eat成为原型为Person实例的对象来实现。

在ES6中,您可以通过将eat一个Proxy对象包裹在person实例中来实现,但此时它已经真正进行了错综复杂。

相反,要么使eat成为真实对象,然后在必要时写回Person,或者只使用命名约定(例如me.eat$steak())。