假设我有课程A
和B
。类B
有一个成员,它是类A
的一个实例,我们称之为this.a
。
在B
方法内部,我尝试以A
方式访问this.a.<methodName>
的方法时,出现以下错误:
TypeError: this.a is undefined
这是我的代码:
function A (name) {
this.name = name;
}
A.prototype.foo = function () {
this.name = this.name.toUpperCase();
};
A.prototype.bar = function () {
this.name = this.name.toLowerCase();
};
function B () {
this.a = new A('Hello, World!');
}
B.prototype.methodsOfA = {
foo: this.a.foo, // here is the problem
bar: this.a.bar //
};
B.prototype.executeMethodOfA = function (methodName) {
this.methodsOfA[methodName]();
//the following works if I delete B.prototype.methodsOfA:
//if (methodName.toLowerCase() === 'foo') this.a.foo();
//else if (methodName.toLowerCase() === 'bar') this.a.bar(); //
};
b = new B();
console.log(b.a.name);
b.executeMethodOfA('foo');
console.log(b.a.name);
b.executeMethodOfA('bar');
console.log(b.a.name);
相反,如果我使用以下定义:
B.prototype.methodsOfA = {
foo: A.prototype.foo,
bar: A.prototype.bar
};
我收到以下错误:
TypeError: this.name is undefined
(可能是因为this
在这种情况下是b
而B
对象没有name
属性。)
那么,如何从this.a.<methodName>
内部访问B
?
注意:这是一个较大问题的简化版本。我知道我问的问题可以通过类/原型继承解决,但理想情况下我希望B
不继承A
。
答案 0 :(得分:2)
我的狡猾感觉说有更好的方法可以解决这个问题,但现在这里有一些工作代码..
function A (name) {
this.name = name;
}
A.prototype.foo = function () {
this.name = this.name.toUpperCase();
};
A.prototype.bar = function () {
this.name = this.name.toLowerCase();
};
function B () {
this.a = new A('Hello, World!');
}
B.prototype.methodsOfA = function (methodName) {
var methods = {
foo: this.a.foo.bind(this.a),
bar: this.a.bar.bind(this.a),
}
return methods[methodName];
};
B.prototype.executeMethodOfA = function (methodName) {
this.methodsOfA(methodName)();
};
b = new B();
console.log(b.a.name);
b.executeMethodOfA('foo');
console.log(b.a.name);
b.executeMethodOfA('bar');
console.log(b.a.name);
你有两个问题:
this
未引用您正在考虑的this
。它指的是窗口,因为methodsOfA
作为普通对象,不会注入this
。我将其更改为正确的方法,现在this
是您想要的this
。this
中调用时,方法仅被赋予预期的a.foo()
指针。将a.foo
分配给另一个名称并在您执行时调用它将丢失this
上下文。如上所示,您可以使用bind()
强制使用正确的上下文。 答案 1 :(得分:1)
this
的方式是错误的。在您的情况下,this
指的是全局上下文,即window
。Object.create(A.prototype)
即可获得A的所有方法。this.methodsOfA[methodName]()
时 - 它使用A
的上下文调用B
的方法。因此,name
上下文中没有名为B
的属性 - 它失败了。 你必须使用A
的上下文调用A
的方法,该方法存储在B
的上下文中,即{} {}}
this.a
this.methodsOfA[methodName].call(this.a);