JavaScript绑定方法在getter属性上不起作用
尝试这样做:JavaScript绑定方法在getter属性上不起作用,javascript,Javascript,尝试这样做: var c = { x: 'other context' }; var o = { x: 'this context', get otherContext () { alert(this.x); }.bind(c) }; o.otherContext; 但是我得到一个语法错误: 未捕获的语法错误:意外标记 用例 你可能会问,为什么我想改变getter的上下文。让我来到这里的用例涉及创建一个可以检索DOM属性的助手对象。辅助对象是在另一个对象中定义的,该
var c = {
x: 'other context'
};
var o = {
x: 'this context',
get otherContext () {
alert(this.x);
}.bind(c)
};
o.otherContext;
但是我得到一个语法错误
:
未捕获的语法错误:意外标记
用例
你可能会问,为什么我想改变getter的上下文。让我来到这里的用例涉及创建一个可以检索DOM属性的助手对象。辅助对象是在另一个对象中定义的,该对象包含对我需要属性的DOM元素的引用。所以,这个helper对象实际上只是一些DOM方法的代理,我会做一些类似的事情:
var ViewObject = function () {
this.el = document.getElementById('id');
var proxy = {
...
get left() {
return this.el.offsetLeft
}.bind(this)
...
};
};
这是一个非常有效的用例。还有一种方法是让父对象的上下文成为这个上下文。(也许代理函数更合适?嗯……我没有想到。但getter是ES5,代理是ES6,仅由evergreens和Edge 13+实现,我认为在ES5的范围内,这个问题仍然非常适用。)
有人能给我一个逻辑解释(引用规范前)为什么更改getter的上下文是非法的。问题是不使用函数表达式。这是一个明确的句法结构
方法定义[产量]:
PropertyName[?收益率](StrictFormalParameters){函数体}
发电机法[产量]
获取属性名称[?收益率](){函数体}
setPropertyName[?Yield](PropertySetParameterList){函数体}
PropertySetParameterList:
形式参数
因为它不是函数表达式,所以您无权访问函数、方法或属性
你可以用它来完成你想要的
对于类代理,您可能希望使用如下内容:
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
您可能需要使用definedProperty
以您想要的方式定义getter。很好。请随意发布一个示例作为答案,即使它与问题并不完全一致。因此,{aFunc(){…}!={aFunc:function(){…}
!?(我并不是真的在做JS比较,只是规范中的属性定义。外部参数用于提供方法的“上下文”)。如果上述情况属实,那么这与getter/setter无关,而是与方法语法有关!我认为defineProperty
解决方案不起作用。似乎绑定函数的这个
值被覆盖为getter的所有者。如果您有var proxy={foo:foo}代码>并且您执行.bind({foo:“bar”})
,调用代理。左侧的将为您提供“foo”
,而不是“bar”
。。。请注意,您也可以使用,这将允许您一次定义多个属性(如果您不想使用默认值,尽管会更加详细)。
let main = new Main();
console.log(main.foo); // -> true
console.log(main.baz()); // -> 8