从自执行匿名成员函数内部访问父原型范围

Access parent prototype scope from inside self-executing anonymous member function

我正在定义一个父对象,我希望它有一个子成员对象,它有自己的函数和私有变量。为了封装函数和变量,我在 Parent 原型中添加了一个自执行的匿名函数。

这是演示问题的代码:

var Parent = function() {
    this.memberVariable = 'hello world';   
}

Parent.prototype.doSomething = function() {
    return this.childObject.doSomething();
};

Parent.prototype.childObject = function() {
    // instead of being Parent, `this` is the Window object. What is the best way to fix this?
    var that = this;
    
    return {
        doSomething: function() {
            // undefined, but should be 'hello world'
            return that.memberVariable;
        }
    }
}();

var parent = new Parent();
console.log(parent.doSomething());

我有一个解决方法是将 Parent 作用域传递给子函数,但这看起来很奇怪,而且似乎必须有更好的解决方案:

var Parent = function() {
    this.memberVariable = 'hello world';   
}

Parent.prototype.doSomething = function() {
    // we pass in `this`
    return this.childObject.doSomething(this);
};

Parent.prototype.childObject = function() {
    return {
        doSomething: function(that) {
            return that.memberVariable;
        }
    }
}();

var parent = new Parent();
console.log(parent.doSomething());

有没有更好的方法来完成这个?

使用call or apply:

Parent.prototype.doSomething = function() {
    return this.childObject.doSomething.call(this);
};

或者您可以使用 bind:

Parent.prototype.childObject = function() {
    return {
        doSomething: (function() {
            // undefined, but should be 'hello world'
            return this.memberVariable;
        }).bind(this)
    }
}();

Parent 构造函数中初始化 childObject。否则,Parent 的所有实例将共享同一个 childObject。这可能不是您想要的。

function Parent() {
  this.childObject = new Child(this); // or something like makeChild(parent), or just an object literal.
}

function Child(parent) {
  this.parent = parent;
}