更深入地了解 Javascript 中的模块机制
Deeper understanding of modules mechanisms in Javascript
我正在更深入地了解 ES6 模块,我注意到以下内容我觉得很有趣,我想将其清除。
观察JavaScript 中的所有模块默认都是单例的,所以
// module a.js
let notification = 10;
export default notification;
假设我们有一个模块 b.js 和 c.js,我们在那里导入 a.js 通知将被共享。通知将是只读的。
观察 b.如果从 returns 一个对象的模块中导出一个函数,则会创建一个新对象。
// module a.js
let notification = 10;
export default () => ({
notification
})
//somewhere in module b.js
import Fn from 'a.js'
let n = Fn().notification; // a new number is created since numbers are immutable in javascript but is this the reason why notification from a.js stays the same?
n = n + 10; // outputs 20
//somewhere in module c.js
import Fn from 'a.js'
let n = Fn().notification; // outputs 10
根据我的理解,这是因为每次都会创建一个新的对象吗?
观察c。如果我们想在模块中共享值,我们需要遵循以下模式吗?
//module a.js
let notification = 10;
export default () => ({
notification,
setNotification() {
notification += 10;
}
})
如果在它导入的模块之一中调用了 setNotification,那么在导入模块 a 的任何其他地方,通知的值将自动为 20。
有人能解释一下为什么会发生上述情况吗?我的观察是否正确?
Based on my understanding, this happens because a new object is created every time?
这不是它发生的原因,但是,是的,每次都会创建一个新对象。但是数字不会改变,因为你没有改变它。您刚刚更改了本地 n
变量,该变量与 Fn
编辑的对象 return 的 notification
属性 完全无关。
If we want to share the value in a module we need to follow the following pattern?
这会起作用,但您不必那样做。这同样有效:
export default {
notification: 10
};
在另一个模块中:
import obj from "./a.js";
console.log(obj.notification); // 10
obj.notification = 20;
console.log(obj.notification); // 20
如果在 上面的代码之后你有第三个模块导入并使用它,他们会看到20
:
import obj from "./a.js";
console.log(obj.notification); // 20
从它的机制上退一步,虽然,一般来说,以这种方式修改您收到的对象可能不是最佳实践,事实上,您甚至可以考虑冻结您 return 来自模块(或根本 returning 函数以外的对象)所以你可以防止使用模块导出的模块之间出现奇怪的串扰。
这是另一个您可能会觉得有启发性的示例:虽然您导入的绑定是只读的,但它是 实时绑定 到导出模块的本地绑定,本地模块可以更改.所以这有效:
source.js
:
export let notification = 10;
export function setNotification(n) {
notification = n;
};
a.js
:
import { notification, setNotification } from "./source.js";
console.log(notification); // 10
setNotification(20);
b.js
:
import { notification, setNotification } from "./source.js";
console.log(notification); // 20
main.js
:
import "./a.js";
import "./b.js";
您可以将导入的绑定视为导出模块中绑定的非常有效 getter(访问器)。
请注意 a.js
和 b.js
运行 的顺序,以及它们看到的值,由 main.js
从它们导入的顺序决定(事实上他们没有任何循环引用或动态导入)。
我正在更深入地了解 ES6 模块,我注意到以下内容我觉得很有趣,我想将其清除。
观察JavaScript 中的所有模块默认都是单例的,所以
// module a.js
let notification = 10;
export default notification;
假设我们有一个模块 b.js 和 c.js,我们在那里导入 a.js 通知将被共享。通知将是只读的。
观察 b.如果从 returns 一个对象的模块中导出一个函数,则会创建一个新对象。
// module a.js
let notification = 10;
export default () => ({
notification
})
//somewhere in module b.js
import Fn from 'a.js'
let n = Fn().notification; // a new number is created since numbers are immutable in javascript but is this the reason why notification from a.js stays the same?
n = n + 10; // outputs 20
//somewhere in module c.js
import Fn from 'a.js'
let n = Fn().notification; // outputs 10
根据我的理解,这是因为每次都会创建一个新的对象吗?
观察c。如果我们想在模块中共享值,我们需要遵循以下模式吗?
//module a.js
let notification = 10;
export default () => ({
notification,
setNotification() {
notification += 10;
}
})
如果在它导入的模块之一中调用了 setNotification,那么在导入模块 a 的任何其他地方,通知的值将自动为 20。
有人能解释一下为什么会发生上述情况吗?我的观察是否正确?
Based on my understanding, this happens because a new object is created every time?
这不是它发生的原因,但是,是的,每次都会创建一个新对象。但是数字不会改变,因为你没有改变它。您刚刚更改了本地 n
变量,该变量与 Fn
编辑的对象 return 的 notification
属性 完全无关。
If we want to share the value in a module we need to follow the following pattern?
这会起作用,但您不必那样做。这同样有效:
export default {
notification: 10
};
在另一个模块中:
import obj from "./a.js";
console.log(obj.notification); // 10
obj.notification = 20;
console.log(obj.notification); // 20
如果在 上面的代码之后你有第三个模块导入并使用它,他们会看到20
:
import obj from "./a.js";
console.log(obj.notification); // 20
从它的机制上退一步,虽然,一般来说,以这种方式修改您收到的对象可能不是最佳实践,事实上,您甚至可以考虑冻结您 return 来自模块(或根本 returning 函数以外的对象)所以你可以防止使用模块导出的模块之间出现奇怪的串扰。
这是另一个您可能会觉得有启发性的示例:虽然您导入的绑定是只读的,但它是 实时绑定 到导出模块的本地绑定,本地模块可以更改.所以这有效:
source.js
:
export let notification = 10;
export function setNotification(n) {
notification = n;
};
a.js
:
import { notification, setNotification } from "./source.js";
console.log(notification); // 10
setNotification(20);
b.js
:
import { notification, setNotification } from "./source.js";
console.log(notification); // 20
main.js
:
import "./a.js";
import "./b.js";
您可以将导入的绑定视为导出模块中绑定的非常有效 getter(访问器)。
请注意 a.js
和 b.js
运行 的顺序,以及它们看到的值,由 main.js
从它们导入的顺序决定(事实上他们没有任何循环引用或动态导入)。