【发布时间】:2018-07-01 19:03:07
【问题描述】:
这有点难以解释。请原谅这个牵强的例子。
我想在同一个函数中访问两个不同的作用域(类全局和对象局部)。所述函数是一个对象方法。
我使用的是babel-preset-react-native,应该是 ES6 (https://facebook.github.io/react-native/docs/javascript-environment.html)。
给定以下示例类:
class Logic {
constructor() {
this.keys = ['Red Key', 'Blue Key'];
}
hasKey = (searchKey) => {
return this.keys.includes(searchKey);
}
allowedToEnter = {
redHouse: () => {
// some logic
return true;
},
// ...
};
houses = [
{
name: 'Red House',
isAccessible: () => {
return this.hasKey('Red Key');
},
shouldAccess__Global: () => {
return /* wrong scope */this.isAccessible() && this.allowedToEnter.redHouse();
},
shouldAccess__Local: function () {
return this.isAccessible() && /* wrong scope */this.allowedToEnter.redHouse();
},
},
// ...
];
}
let logic = new Logic();
console.log(logic.houses[0].shouldAccess__Global());
// returns: isAccessible is not a function
console.log(logic.houses[0].shouldAccess__Local());
// returns: Cannot read property 'redHouse' of undefined
定义箭头函数将类范围绑定到this。使用经典的函数语法,它将this 绑定到它的“所有者”的范围内,即数组内的房屋对象。我明白,在这两种情况下,这都是正确的行为。
是否有一种优雅的方式来编写 shouldAccess 方法,同时提供对两个范围的访问权限?
我想出的一个可能的解决方案如下:
shouldAccess__withHelper: function () {
return this.isAccessible() && this.helper().allowedToEnter.redHouse();
},
helper: () => {
return this;
},
这不是优雅的想法。我的阵列中有大量的房屋物品。给每个对象一个辅助函数很糟糕。
我知道整个数据结构有点复杂,并不理想。我不是在寻求关于如何更好地构建我的代码的建议。 我正在处理给定结构中的大量逻辑,重构所有内容将是一个巨大的痛苦。
【问题讨论】:
-
你不能在函数外声明一个变量,比如...
var outerThis = this -
根据显示的代码,这应该可以工作:
var globalThis = this; class Logic { ... shouldAccess: function () { this.isAccessible() && globalThis.allowedToEnter.redHouse() }? -
ty,但是这两个建议都不起作用。
shouldAccess__Local根本无法访问类范围,因此在类构造函数中定义outerThis = this没有帮助。类外的var globalThis = this;不允许我访问类函数。 -
根据经验,在 JS OOP 中,
this应该引用类实例。这个问题表明类设计出了问题。您可以使用class关键字包装所有内容并不意味着应该这样做。为什么会有Logic的东西?这听起来不像是一个类的合适实体。它不使用状态,因此不能从实例化中受益,这表明它不应该是一个类。 -
你说得对,我几乎将遗留代码封装在一个类中。但它确实订阅了一个状态,为了简化,我只是在示例中删除了它。不过你说得很好,也许上课不是正确的方法。
标签: javascript ecmascript-6 scope