这个脚本是怎么回事
whats going on in this script
很抱歉,我不能非常具体地说明脚本发生了什么。
我写这段脚本是为了理解 java 脚本中的 属性 修改。我有一个变量 ctx
,它有两个属性 ctx.exports
和 ctx.module.exports
。正如您在下面看到的 int eh 代码,我已经建立了关系 ctx.module.exports = ctx.exports
所以当 ctx.exports
被修改时 ctx.module.exports
保持相同的值。
但下面的脚本另有建议。
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
ctx.exports = {
h: "hello"
}
if (ctx.exports == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
然而,在这种情况下,当我将 ctx.exports
值存储到局部变量 exports
时。 exports
在修改 ctx.exports
时与 ctx.module.exports
相等
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
var exports = ctx.exports;
ctx.exports = {
h: "hello"
}
if (exports == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
cn 谁能给我解释一下这种情况是怎么回事?这是 java 脚本中的一种范围界定吗?这个有专有名称吗?
编辑
正如第一个答案所解释的那样,ctx.module.exports
正在检查 {}
这就是它匹配的原因。但在那种情况下,为什么会失败
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
var exports = ctx.exports;
ctx.exports = {
h: "hello"
}
if ({} == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
看看比较的是什么。在第一个示例中,您将 ctx.module.exports
设置为引用 ctx.exports
,这是一个空对象:{}
。然后你用新值覆盖 ctx.exports
:{ h: "hello" }
。 ctx.module.exports
保留了对原始对象的引用,而 ctx.exports
现在引用了一个不同的对象:您正在将 {}
与 { h: "hello" }
.
进行比较
在第二个示例中,您再次用新对象覆盖 ctx.exports
,但您正在比较对原始对象的两个引用:{}
到 {}
。是一场比赛。
编辑 - 为了更清楚一点
设置变量的值时,您将名称链接到引用。覆盖该变量会创建一个同名的新引用,但不会修改该引用,这就是覆盖 ctx.exports
对其他任何一个引用都没有影响的原因。
编辑对问题的回复编辑
你不能这样比较对象。 {} !== {}
因为每个对象字面量声明都会创建一个新的 Object 实例。可以比较您的引用的原因是因为它们是对同一对象的引用,即由 ctx.exports = {}
.
创建的对象
更多编辑!
通过比较每个对象的 JSON 值,您可以看到效果:JSON.stringify({}) == JSON.stringify(ctx.module.exports)
为真,因为它比较的是相同的字符串; {} == ctx.module.exports
是假的,因为它比较的是不同的对象,尽管两个对象在构造上是相同的。
我认为你的问题不在于比较,而在于赋值:
ctx.module = {
exports: ctx.exports
}
这会创建一个 ctx.exports
到 ctx.module.exports
的 "link",因为对象本身没有被复制,而只是它被分配给 ctx.module.exports
的引用。
但是赋值后
ctx.exports = {
h: "hello"
}
link 的一部分被覆盖。
如果你想在不破坏 link 的情况下向 sys.exports
添加一个新值,你可以使用这个:
ctx.exports.h = "hello";
很抱歉,我不能非常具体地说明脚本发生了什么。
我写这段脚本是为了理解 java 脚本中的 属性 修改。我有一个变量 ctx
,它有两个属性 ctx.exports
和 ctx.module.exports
。正如您在下面看到的 int eh 代码,我已经建立了关系 ctx.module.exports = ctx.exports
所以当 ctx.exports
被修改时 ctx.module.exports
保持相同的值。
但下面的脚本另有建议。
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
ctx.exports = {
h: "hello"
}
if (ctx.exports == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
然而,在这种情况下,当我将 ctx.exports
值存储到局部变量 exports
时。 exports
在修改 ctx.exports
ctx.module.exports
相等
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
var exports = ctx.exports;
ctx.exports = {
h: "hello"
}
if (exports == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
cn 谁能给我解释一下这种情况是怎么回事?这是 java 脚本中的一种范围界定吗?这个有专有名称吗?
编辑
正如第一个答案所解释的那样,ctx.module.exports
正在检查 {}
这就是它匹配的原因。但在那种情况下,为什么会失败
var ctx = {};
ctx.exports = {};
ctx.module = {
exports: ctx.exports
}
var exports = ctx.exports;
ctx.exports = {
h: "hello"
}
if ({} == ctx.module.exports) {
console.log("hi");
} else {
console.log("hey");
}
看看比较的是什么。在第一个示例中,您将 ctx.module.exports
设置为引用 ctx.exports
,这是一个空对象:{}
。然后你用新值覆盖 ctx.exports
:{ h: "hello" }
。 ctx.module.exports
保留了对原始对象的引用,而 ctx.exports
现在引用了一个不同的对象:您正在将 {}
与 { h: "hello" }
.
在第二个示例中,您再次用新对象覆盖 ctx.exports
,但您正在比较对原始对象的两个引用:{}
到 {}
。是一场比赛。
编辑 - 为了更清楚一点
设置变量的值时,您将名称链接到引用。覆盖该变量会创建一个同名的新引用,但不会修改该引用,这就是覆盖 ctx.exports
对其他任何一个引用都没有影响的原因。
编辑对问题的回复编辑
你不能这样比较对象。 {} !== {}
因为每个对象字面量声明都会创建一个新的 Object 实例。可以比较您的引用的原因是因为它们是对同一对象的引用,即由 ctx.exports = {}
.
更多编辑!
通过比较每个对象的 JSON 值,您可以看到效果:JSON.stringify({}) == JSON.stringify(ctx.module.exports)
为真,因为它比较的是相同的字符串; {} == ctx.module.exports
是假的,因为它比较的是不同的对象,尽管两个对象在构造上是相同的。
我认为你的问题不在于比较,而在于赋值:
ctx.module = {
exports: ctx.exports
}
这会创建一个 ctx.exports
到 ctx.module.exports
的 "link",因为对象本身没有被复制,而只是它被分配给 ctx.module.exports
的引用。
但是赋值后
ctx.exports = {
h: "hello"
}
link 的一部分被覆盖。
如果你想在不破坏 link 的情况下向 sys.exports
添加一个新值,你可以使用这个:
ctx.exports.h = "hello";