我在ES6中导出一个工厂函数,它返回一个带有属性的对象。 在调用工厂时,会创建对象,但其值不会更新。
示例:
// factory.js
let counter = 1;
let factory = () => {
let increment = function(){
counter++;
}
return { counter, increment };
}
export default factory;
// main.js
import factory from './factory';
let f = factory();
console.log(f.counter); // =>1
f.increment();
console.log(f.counter); // => stil 1, not 2?
有人可以解释为什么会这样吗?它是ES6功能,还是与我使用webpack和babel(es2015-preset)这一事实有关?
我发现了这一点,但这并没有描述相同的用例:http://exploringjs.com/es6/ch_modules.html#sec_imports-as-views-on-exports
答案 0 :(得分:3)
在JavaScript primitive types中passed by value。
let counter = 1;
let factory = () => {
...
// The property `counter` in this object gets passed a value of the `counter` declared in the scope of `factory.js`.
// It does not get a reference.
return { counter, increment };
}
当您从factory
函数返回对象时,其属性counter
会从{{1}范围内声明的counter
中分配值 }}。这实质上意味着对象的factory.js
属性收到了值的副本 - 没有任何内容链接counter
变量和counter
属性的值。
counter
当您递增let counter = 1;
let factory = () => {
let increment = function () {
// The `++` operates on the `counter` variable declared in the scope of `factory.js`.
// There is no link between the value `counter` in the scope of `factory.js` and the `counter` as the property of the object returned.
// As a result when the `counter` variable is incremented, the `counter` property remains the same as the value initially passed to it.
counter++;
};
};
时,您正在递增counter
范围内声明的变量的值。变量的值是factory.js
因此是原语。原始值按值传递,因此变量Number
和属性counter
之间没有链接。
希望所有这一切都有意义。如果您想更多地阅读传递值的想法(与通过引用传递相比),您可以看到以下StackOverflow问题:
此时您可能会问如何解决此问题??
您需要增加counter
,而不是递增counter
。像这样:
this.counter
这是有效的,因为let increment = () => {
this.counter++;
};
的上下文是从函数this
返回的对象。 factory
属性位于您指定调用counter
的结果的变量上。