我试图找到使用这行代码的原因
var cc = cc = cc || {};
例如在这个地方的 Cocos2D JavaScript 库中,但我找不到任何合理的理由。就设置而言,单一分配默认值可以,但双重分配?有谁知道其中的原因?
我试图找到使用这行代码的原因
var cc = cc = cc || {};
例如在这个地方的 Cocos2D JavaScript 库中,但我找不到任何合理的理由。就设置而言,单一分配默认值可以,但双重分配?有谁知道其中的原因?
该代码等价于以下内容:
var cc;
cc = cc || {};
cc = cc;
这显然是一个错误。
更新。我对这个话题做了更多的研究,这是一件有趣的事情:
每当您使用var
关键字时,它都会在当前范围内创建一个新变量,除非它已经存在于当前范围内。基本上这段代码:
var cc = 1;
function test() {
var cc = cc || {};
return cc;
}
test();
将始终产生{}
,无论cc
( 在全局范围内 ) 的初始值是什么。特别是这段代码:
var cc = [expression];
相当于:
var cc;
cc = [expression];
尽管仅当当前范围内不存在时才var cc;
创建新变量。 cc
更新 2.什么操作优先令人困惑,因为在 OP 的代码中,两个=
符号实际上并不相同。第一个表示变量声明,因为var
它前面有一个关键字。第二个是任务。这就是为什么
var x = y = z;
相当于
var x;
y = z;
x = z;
(请注意,var
关键字仅适用于x
)而
x = y = z;
相当于
y = z;
x = z;
(请注意操作y=z
返回z
,这并不重要(可能很y
明显)但值得注意)
结论:左侧的变量声明总是在评估右侧并将右侧分配给左侧之前。
这个一直让我很烦,所以我玩了一个游戏并做了一些测试,这是我的发现。
我将展示两个不同的脚本,它们会产生两种不同的结果,从而解释为什么有人可能会使用一个而不是另一个。然而,使用其中任何一种的原因取决于编码器,并且将基于他们想要发生的效果。
请注意,出于示例目的,我将使用实际值而不是空对象。
通常,您可能希望看到以下示例正在使用:
var cc = cc || 1;
这将创建一个名为的新变量cc
,并给出现有(在同一范围内)变量的值,或1
. 此方法不会更改原始变量,尽管在实践中它似乎具有已更改的效果,因为您无法随后引用原始变量,因为它具有相同的名称。
这可以通过使用不同的变量名来测试,例如:
var aa;
alert(aa);
var cc = aa || 1;
alert(aa);
alert(cc);
(示例)在这里您可以看到aa
永远不会改变。
接下来我们看一下有问题的代码:
var cc = cc = cc || 1;
这实际上会改变原始变量并创建一个新的本地变量。同样,当变量具有相同名称时,不容易看到效果。但是,如果我们像上面一样进行名称更改,我们可以看到真正的效果:
var aa;
alert(aa);
var cc = aa = aa || 1;
alert(aa);
alert(cc);
(示例)这次我们可以看到aa
确实发生了变化。
总之,您可能永远不会真正看到使用一个比另一个(具有相同的变量名)产生任何影响,但我很好奇如果可以在分配之前在某处引用原始数据会发生什么影响,因此选择使用哪个实际上会产生影响。我会看看我是否能找到一些东西来展示这一点。
这段代码显然是一个错误。作者的想法可能是将全局变量和内部范围变量设置为相同的值,但这个表达式总是会失败。它不仅无法设置外部变量,而且总是使用 return {}
。
这个表达式失败的原因是声明的变量在赋值之前被设置为未定义。由于这行代码尝试分配一个与自身同名的变量,并且由于 JavaScript 首先评估内部范围变量,因此在分配时cc
将始终解析为未定义的内部 self,这否定了逻辑评估并返回{}
。
在代码中查看它的另一种方法:
var cc; //cc is set to 'undefined'
cc = cc || {}; //which becomes equivalent to:
cc = undefined || {}; //which finally evaluates to:
cc = {}