一、引子
var a = {n:1};
a.x = a = {n:2};
alert(a.x); // --> undefined
这是蔡蔡在看jQuery源码 时发现这种写法的。 以上第二句 a.x = a = {n:2}
是一个连续赋值表达式。 这个连续赋值表达式在引擎内部究竟发生了什么?是如何解释的?
二、猜想
猜想1:从左到右赋值,a.x 先赋值为 {n:2},但随后 a 赋值为 {n:2}, 即 a 被重写了,值为 {n:2},新的 a 没有 x属性,因此为undefined。
步骤如下
a.x = {n:2};
a = {n:2};
这种解释得出的结果与实际运行结果一致,貌似是对的。
注意猜想1中 a.x 被赋值过。
猜想2:从右到左赋值,a 先赋值为{n:2},a.x 发现 a 被重写后(之前a是{a:1}), a.x = {n:2} 引擎限制a.x赋值,忽略了。
步骤如下:
a = {n:2};
a.x 未被赋值{n:2}
等价于 a.x = (a = {n:2})
,即执行了第一步,这样也能解释a.x为undefined了。
注意猜想2中a.x压根没被赋值过。
三、证明
上面两种猜想相信多数人都有,群里讨论呆呆认为是猜想1, 我认为是猜想2。其实都错了。 我忽略了引用的关系。
如下,加一个变量b,指向a。
var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> [object Object]
发现a.x仍然是undefined,神奇的是 b.x 并未被赋值过(比如:b.x={n:2})
,却变成了 [object Object]
。 b 是指向 a({n:1})
的,只有 a.x = {n:2}
执行了才说明b是有x属性的。 实际执行过程:从右到左,a 先被赋值为 {n:2}
,随后a.x被赋值 {n:2}
。
a = {n:2};
a.x = {n:2};
等价于
a.x = (a = {n:2});
与猜想2的区别在于a.x 被赋值了,猜想2中并未赋值。 最重要的区别,第一步 a = {n:2}
的 a 指向的是新的对象{n:2}
, 第二步 a.x = {n:2}
中的 a 是 {a:1}
。
即在这个连等语句
a.x = a = {n:2};
a.x 中的a指向的是 {n:1}
,a 指向的是 {n:2}
。
a.x = a = {n:2}
│ │
{n:1}<──┘ └─>{n:2}
四:解惑
这篇写完,或许部分人看完还是晕晕的。 因为里面的文字描述实在是绕口。
最初我在理解这个连等赋值语句时
var a = {n:1};
a.x = a = {n:2};
认为引擎会限制a.x的重写(a被重写后),实际却不是这样的。 指向的对象已经不同了。引擎也没有限制a.x={n:2}的重写。
五:结束
呵,以另一个连续赋值题结束。 fun执行后,这里的 变量 b 溢出到fun外成为了全局变量。
想到了吗?
function fun(){
var a = b = 5;
}
fun();
alert(typeof a); // --> undefined
alert(typeof b); // --> number
文章来源:http://justjavac.com/javascript/2012/04/05/javascript-continuous-assignment-operator.html
分享到:
相关推荐
这说明了JavaScript中的赋值运算的右结合性如何影响连续赋值。在编写连续赋值代码时,开发者需要考虑到这一点,以避免因理解错误而导致的bug。 此外,当涉及到对象和属性的赋值时,还应特别注意JavaScript中对象...
JS 中变量的连续赋值(实例讲解) 在 JavaScript 中,变量的连续赋值是一种常见的语法结构,它可以将多个变量...通过了解连续赋值的机理,可以更好地理解 JavaScript 的变量赋值机制,并写出更加简洁和高效的代码。
在本项目中,我们将探讨如何使用HTML5、CSS3和JavaScript技术来创建一个简单的四则运算计算器。这个计算器能够执行基本的加法、减法、乘法和除法操作,对于初学者来说是一个很好的实践项目,它能帮助理解前端开发的...
在"javascript input赋值"这个压缩包文件中,可能包含了一些示例代码或者教程,用于演示如何在实际项目中应用这些技术。通过学习和理解这些示例,开发者能够更好地掌握JavaScript中对input元素的操作,提高前端开发...
在JavaScript中,连续赋值是一种常见的操作,它允许开发者将一个值赋给多个变量。通常情况下,连续赋值不会引起混淆,但是当涉及对象和引用时,就可能出现一些不易察觉的陷阱。了解这些陷阱和连续赋值的内部机制对于...
加法(+)、减法(-)、乘法(*)和除法(/)是基础,但为了支持括号和更复杂的运算,我们需要了解优先级和运算顺序。在JavaScript中,括号用于改变运算顺序,表达式`a * (b + c)`会先计算括号内的`b + c`,然后将...
此外,JavaScript还支持复合赋值运算符,如`+=`, `-=`等,它们可以简化代码并进行连续运算: ```javascript a += b; // 等价于 a = a + b a -= b; // 等价于 a = a - b ``` 在HTML5中,我们可以利用`<canvas>`元素...
此函数是我自己写的,虽然在网上可以搜到很多,不过我找到的都是在算法中存在基本的浮点数的运算,导致结果仍然是错误的。由于刚刚学写JS,所以可能考虑不够周全,望大家批评指正。 代码中加了四舍五入函数,是网上...
在构建Web应用时,PHP、JavaScript和HTML之间的变量赋值和传递是至关重要的。这篇文章主要讲解了如何在这些技术之间进行数据交互。 首先,我们来看HTML超链接如何传递值。在HTML中,我们可以使用`<a>`标签创建链接...
var num1 = prompt('请输入第一个数:'); var re = prompt('请输入你要进行的运算符:'); var num2 = prompt('请输入第二个数:'); function getSum(num1,re,num2,) { switch (re) { case '+': ...
JavaScript是一种广泛应用于Web开发的脚本语言,它在处理四则运算时提供了多种方式,包括基本的算术运算符和位运算符。本篇将详细探讨如何利用位移操作实现四则运算,以及这些方法在实际编程中的应用。 在...
JavaScript语法基于ECMAScript规范,包括变量声明(var、let、const)、数据类型(如字符串、数字、布尔值、对象、数组等)、运算符(算术、比较、逻辑、位运算等)、流程控制(条件语句、循环结构)以及函数等。...
**JavaScript全方位解析** JavaScript,简称JS,是一种广泛应用于网页和网络应用的脚本语言,尤其在前端开发领域占据着核心地位。它与HTML和CSS一起,构成了网页开发的三驾马车,使得网页具备交互性、动态性和实时...
本文主要探讨了JavaScript中几个易出错的操作符类别,包括算术运算符、比较运算符、逻辑运算符以及赋值和一元运算符的运算顺序和优先级。 首先,我们来看算术运算符。在JavaScript中,有些特殊的字面量值,如`NaN`...
JavaScript中的数学运算主要涵盖基本算术运算和使用Math对象的高级计算。JavaScript支持常见的加法(+), 减法(-), 乘法(*), 除法(/)以及取模(%)运算符。此外,它还提供了处理特殊计算结果的能力,如正负Infinity和NaN...
10. 表达式运算:Javascript中的表达式运算可以是算术运算、比较运算、逻辑运算等,例如`a++==b?a:b`的结果是根据条件判断的结果而定的。 11. Radio按钮默认选中:在Html中,可以使用checked属性来设置Radio按钮的...
在编写代码时我们有时候会碰到需要自己解析四则运算表达式的情况,本文简单的介绍使用JavaScript实现对简单四则运算表达式的解析。 一、熟悉概念 中缀表示法(或中缀记法)是一个通用的算术或逻辑公式表示方法, ...
在现代Web开发中,HTML5、CSS3和JavaScript是构建交互式网页的三大核心技术。...通过学习和理解这些文件,开发者可以了解到如何利用HTML5、CSS3和JavaScript的组合实现一个完整的字符串数学运算应用。
《精通JavaScript(源代码)》是由jQuery之父John Resig撰写的高级JavaScript技术书籍,它不仅深入探讨了JavaScript的核心概念,而且重点解析了jQuery库的内部工作机制,为读者揭示了JavaScript编程的深层次奥秘。...