背景
今天服务器着火了,因为应用程序崩溃了。检查服务器后,我发现内存一直在上升,导致 PM2 最终杀死并重新启动进程。
代码
这是因为我做了修复造成的。原始代码如下:
const cache = this.cache[script] = this.cache[script] || {};
看到之后我想:“这肯定是一个错字,原作者的意思是别的,像这样”:
const cache = this.cache[script] || {};
问题
通过修复那一行,内存开始增长和积累,直到填满整个服务器。
我很震惊......显然我不得不将它恢复到原始版本......
问题
这两行有什么区别?
最佳答案
第一个写{}
至 this.cache[script]
如果 this.cache
中没有属性使用变量中的名称 script
(或者有但它的值是假的)。第二个没有。
所以这意味着如果您多次调用此代码(或将其放在多个位置),使用第一个代码,所有这些代码最终将共享一个对象(存储在 this.cache[script]
上),但随着第二个代码,他们都将创建和使用自己的新对象。
这就是内存膨胀的原因,代码从不缓存对象并不断创建新对象。
例子:
class Example {
constructor() {
this.cache = Object.create(null);
}
getTheCache1(script) {
const cache = this.cache[script] || {};
return cache;
}
getTheCache2(script) {
const cache = this.cache[script] = this.cache[script] || {};
return cache;
}
}
const e1 = new Example();
const e1c1 = e1.getTheCache1("foo");
const e1c2 = e1.getTheCache1("foo");
console.log("e1c1 === e1c2? " + (e1c1 === e1c2));
const e2 = new Example();
const e2c1 = e1.getTheCache2("foo");
const e2c2 = e1.getTheCache2("foo");
console.log("e2c1 === e2c2? " + (e2c1 === e2c2));
或者一个更简单的例子:
let a; // a starts out undefined
console.log("const b = a || {};");
const b = a || {};
console.log("typeof a: " + typeof a); // "typeof a: undefined"
console.log("typeof b: " + typeof b); // "typeof b: object"
console.log("a === b? " + (a === b)); // "a === b? false"
console.log("const c = a = a || {};");
const c = a = a || {};
console.log("typeof a: " + typeof a); // "typeof a: object"
console.log("typeof c: " + typeof c); // "typeof c: object"
console.log("a === c? " + (a === c)); // "a === c? true"
.as-console-wrapper {
max-height: 100% !important;
}
所有这一切都有效,因为分配的结果是分配的值。所以在这里:
let a, b;
b = a = a || 42;
发生的事情是:
- 表达式
a || 42
被评估,产生值42
自undefined || 42
是42
. - 表达式
a = <value>
被评估,其中<value>
是步骤 1 的结果。因此42
被分配给a
.该表达式的结果是分配的值 (42
)。 - 表达式
b = <value>
被评估,其中<value>
是第 2 步的结果。所以42
被分配给b
.
但没有 a =
其中一部分:
let a, b;
b = a || 42;
只是
- 表达式
a || 42
被评估,产生值42
自undefined || 42
是42
. - 表达式
b = <value>
被评估,其中<value>
是步骤 1 的结果。因此42
被分配给b
.
...离开 a
不变。
关于javascript - 这两行代码有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51304982/