JavaScript 工厂函数在闭包范围之外修改变量



为什么变量"OnDone"在出厂范围内保持不变?

const foo = () => {
let OnDone = null;
const Do = function() {
console.log(OnDone);
if (typeof OnDone === 'function')
OnDone();
}
return {
Do,
OnDone
};
}
let f = foo();
f.OnDone = () => {
console.log('OnDone');
};
f.Do();

输出为空。 https://jsfiddle.net/xe4j9hmc/6/

let onDone = null定义一个变量onDonefoo函数作用域内不是属性,而是当你这样做时

f.onDone它为f上的onDone属性增加了价值,可以使用this.onDone访问,但在代码中,您使用的是onDone,它仍然引用在本地范围内定义的onDone


你可能想这样做

function foo(){
this.OnDone = null;
const Do = function() {
console.log(this.OnDone);
if (typeof this.OnDone === 'function')
this.OnDone();
}
return {Do, onDone:this.OnDone};
}
let f = new foo();
f.OnDone = () => {
console.log('OnDone');
};
f.Do();

其他答案已经解释了问题是什么,但我认为查看该问题的简化示例会很有用:

var foo = null;
var obj = {foo};
obj.foo = 42;
console.log(foo);

在这里,记录foo的值也将打印null。为obj.foo属性分配新值不会更改变量foo。这是因为当我们使用{foo}创建对象时,foo值的副本被分配给该属性。

在特定情况下,您希望对属性的赋值也更改变量。您可以通过二传手来做到这一点(我们添加一个吸气器以获得良好的衡量(:

const foo = () => {
let OnDone = null;
const Do = function() {
console.log(OnDone);
if (typeof OnDone === 'function')
OnDone();
}
return {
Do,
get OnDone() {
return OnDone;
},
set OnDone(value) {
OnDone = value;
},
};
}
let f = foo();
f.OnDone = () => {
console.log('OnDone');
};
f.Do();

现在,当您分配给属性f.OnDone时,我们实际上是在执行 setter 函数,该函数反过来更新变量值。

return { OnDone };

等于。。。

return { onDone: onDone };

或者换句话说:局部变量onDone解析,它解析的对象引用存储在返回的对象onDone属性中。两者都将引用相同的东西,* 但是 * 如果你重新分配局部变量或对象属性,这将改变 * reference*,因此属性和变量将引用不同的东西。

要解决此问题,请更改对象本身:

const context = { onDone }
context.Do = function () {
// Access context.onDone here
};
return context;

或者,作为替代方案,由于f.Do()将在thisf的情况下调用Do,您可以从Do函数中this.OnDone访问对象属性。

相关内容

  • 没有找到相关文章

最新更新