层层递进,层层剥开,var foo = {n: 1}; var bar = foo; foo.x = foo = {n: 2}; 的本质
2023-09-01 08:28:53
前言
最近准备归纳总结一下前端的知识,突然看到了这样一道题:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
乍一看,脑子确实一下转不过来,仔细一看也似懂非懂的。那么接下来我们就一起来解析一下这道题目。
赋值运算符的运算顺序
运算符的优先级决定了表达式中各个运算符的执行顺序。赋值运算符的优先级是最低的,这意味着它将在表达式中的其他运算符之后执行。例如,在以下表达式中,赋值运算符=
将在加法运算符+
之后执行:
var foo = 1 + 2;
这将导致变量foo
的值为3
。
运算符优先级
在 JavaScript 中,运算符的优先级分为以下几个级别:
- 一元运算符(如
+
、-
、!
) - 二元运算符(如
+
、-
、*
、/
) - 赋值运算符(如
=
、+=
、-=
) - 比较运算符(如
==
、!=
、<
、>
) - 逻辑运算符(如
&&
、||
、!
)
运算符的优先级越高,它将在表达式中执行得越早。例如,乘法运算符*
的优先级高于加法运算符+
,这意味着在以下表达式中,乘法运算符将在加法运算符之前执行:
var foo = 1 * 2 + 3;
这将导致变量foo
的值为5
。
var foo =; var bar = foo; foo.x = foo =;的本质
现在,让我们回到题目中的那道题:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
这道题之所以令人困惑,是因为它使用了赋值运算符和操作符优先级这两个概念。首先,我们来看看赋值运算符=
。在 JavaScript 中,赋值运算符=
用于将一个值赋给一个变量。例如,在以下代码中,我们使用赋值运算符=
将值1
赋给变量foo
:
var foo = 1;
这将导致变量foo
的值为1
。
接下来,我们来看看操作符优先级。在 JavaScript 中,赋值运算符=
的优先级是最低的,这意味着它将在表达式中的其他运算符之后执行。例如,在以下代码中,赋值运算符=
将在加法运算符+
之后执行:
var foo = 1 + 2;
这将导致变量foo
的值为3
。
现在,让我们回到题目中的那道题:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
首先,我们来看第一行代码:
var foo = {n: 1};
这行代码将一个对象{n: 1}
赋给变量foo
。
接下来,我们来看第二行代码:
var bar = foo;
这行代码将变量foo
的值(即对象{n: 1}
)赋给变量bar
。这意味着变量bar
和变量foo
指向同一个对象。
接下来,我们来看第三行代码:
foo.x = foo = {n: 2};
这行代码首先将字符串'x'
赋值给对象的属性foo.x
。然后,它将对象{n: 2}
赋给变量foo
。这意味着变量foo
现在指向了一个新的对象,而变量bar
仍然指向原来的对象。
因此,最终的结果是:
- 变量
foo
指向对象{n: 2}
。 - 变量
bar
指向对象{n: 1}
。
总结
通过对这道题的解析,我们了解到了赋值运算符和操作符优先级这两个概念。我们还了解到了这道题的本质:首先将一个对象赋给变量foo
,然后将变量foo
的值(即对象)赋给变量bar
,最后将字符串'x'
赋值给对象的属性foo.x
,然后将一个新的对象赋给变量foo
。