尝试这样做:
var c = {
x: 'other context'
};
var o = {
x: 'this context',
get otherContext () {
alert(this.x);
}.bind(c)
};
o.otherContext;
但我得到Syntax Error
:
未捕获的SyntaxError:意外的令牌。
您可能会问,为什么我可能想要更改getter上下文。在这里引导我的用例涉及创建一个将检索DOM属性的辅助对象。帮助器是在另一个对象中定义的,该对象持有对我需要属性的DOM元素的引用。所以,这个辅助对象实际上只是一些DOM方法的代理,实际上,我会做类似的事情:
var ViewObject = function () {
this.el = document.getElementById('id');
var proxy = {
...
get left() {
return this.el.offsetLeft
}.bind(this)
...
};
};
恕我直言,这是一个非常有效的用例。拥有父对象的this
上下文的一个有用。 (也许代理功能可能更合适?嗯......我没有想到这一点。仍然是吸气剂是ES5,代理是ES6,只有常青树和Edge 13+实现,我认为在ES5的范围内问题仍然很非常适用。)
答案 0 :(得分:11)
问题是method syntax没有使用函数表达式。它是一个定义的句法结构。
MethodDefinition [Yield] :
PropertyName [?收益率] ( StrictFormalParameters ) { 功能体 }
GeneratorMethod [?收率]
获取 PropertyName [?收益率] ( ) { 功能体 }
设置 PropertyName [?收益率] ( PropertySetParameterList ) { 功能体 }
PropertySetParameterList :
FormalParameter
由于它不是函数表达式,因此您无权访问函数方法或属性。
您可以使用Object.defineProperty
完成所需内容。
var proxy = { ... };
Object.defineProperty(proxy, 'left', {
get: function() {
return this.el.offsetLeft;
}.bind(this)
});
答案 1 :(得分:3)
对于类代理,您可能希望使用以下内容:
class Main {
constructor() {
this._adapter = new Adapter();
return this._createProxy();
}
_createProxy() {
return new Proxy(this, {
get(me, propertyName) {
if (typeof me._adapter[propertyName] === 'function') {
return me._adapter[propertyName].bind(me._adapter);
}
return (function () {
return me._adapter[propertyName];
}.bind(me._adapter))();
}
});
}
}
class Adapter {
constructor() {
this._foo = true;
this._yuk = 2;
}
get foo() {
return this._foo;
}
baz() {
return 4*this._yuk;
}
}
这样,getter和方法都将包含在正确的上下文中:
let main = new Main();
console.log(main.foo); // -> true
console.log(main.baz()); // -> 8