Javascript 为什么foo.x=foo={n:2}中没有定义foo.x的值?

Javascript 为什么foo.x=foo={n:2}中没有定义foo.x的值?,javascript,Javascript,此代码: var foo = {n: 1}; var bar = foo; foo.x = foo = {n: 2}; 你能解释一下什么是: foo.x = foo = {n: 2}; 我看到{n:2}被分配给foo。为什么未定义分配给foo.x?Doesfoo={n:2}返回未定义?,因为左侧的属性访问foo.x在右侧之前进行评估 让我们通过为正在计算的临时表达式指定新名称,更清楚地了解代码的实际功能: var foo0 = {n: 1}; var foo1 = {n: 2}; foo0.

此代码:

var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
你能解释一下什么是:

foo.x = foo = {n: 2};

我看到
{n:2}
被分配给
foo
。为什么
未定义
分配给
foo.x
?Does
foo={n:2}返回
未定义

,因为左侧的属性访问
foo.x
在右侧之前进行评估

让我们通过为正在计算的临时表达式指定新名称,更清楚地了解代码的实际功能:

var foo0 = {n: 1};
var foo1 = {n: 2};
foo0.x = foo1;
foo0 = foo1;
console.log(foo0.x);
因此
foo0.x
foo1.x
未定义的


在原始代码中,您可以看到
bar.x
{n:2}
,确认了这一解释。

因为您将foo分配给了一个具有单个属性的对象,
{n:2}


在JavaScript中,表达式从右向左求值。因此,当您尝试访问
foo.x
时,您正试图从新分配的foo值
{n:2}
中获取
x
的值,根据JavaScript规范,这是
未定义的

,左侧总是首先求值:

12.14.4运行时语义:评估

AssignmentExpression[In,Yield]:LeftHandSideExpression[?Yield]=AssignmentExpression[?In,Yield]

如果LeftHandSideExpression既不是ObjectLiteral也不是ArrayLiteral,则
1.让lref作为计算LeftHandSideExpression的结果

如果向
foo
对象添加另一个引用,则可以清楚地看到:

var ref = {n:1};
var foo = ref;
var bar = foo;
foo.x = foo = {n: 2};
ref.x
之所以存在,是因为
foo.x
引用了
foo

的未修改值,赋值表达式的左侧将首先求值,即使运算符具有从右到左的优先级。因此,表达式
foo.x=foo={n:2}
foo.x=(foo={n:2})
的计算方式相同:

  • 计算左侧表达式
    foo.x
    以获得引用,右侧表达式的值将被分配到该引用。

  • 对右侧表达式求值,以获取将要指定的值。右侧是另一个赋值表达式,因此其求值方式相同:

  • 评估
    foo
    以确定分配到的位置
  • 计算创建对象的表达式
    {n:2}
    ,以确定要分配的值
  • {n:2}
    分配给foo,并返回
    {n:2}


  • 将右侧表达式求值的值(
    {n:2}
    )分配给在步骤1中解析为
    foo.x
    的引用(之前
    foo
    分配了新值)。这也与
    bar.x
    相同,因为前面一行上有赋值
    bar=foo

  • 完成此操作后,
    bar
    仍作为引用的原始对象将具有一个
    x
    属性,该属性引用创建的第二个对象
    foo
    也是对第二个对象的引用,所以
    foo===bar.x

    为什么要进行向下投票?这是一个有趣的问题。@Juhana你介意修复你的编辑吗?@djechlin有什么问题吗?@Juhana你恢复了格式和语言的改进。@djechlin我看不出“这段代码”是如何改进的,但是YMMV。那么“foo.x=”。。。do?@djechlin它被分配给foo,但是foo被重写为一个没有x值的对象我现在知道这是正确的,但这并不奇怪,它让人困惑。看起来我们有一个赢家。
    foo.x=(foo={n:2})
    甚至有意义吗,我刚刚在chrome上测试过,它也有同样的功能results@johnny5如果
    foo
    不是一个对象,那就没有意义了,但从第一句话开始,它就是一个对象。完整重复问题链接的最佳答案。@Paulpro是foo.x=foo={n:2};分解为foo.x={n:2};foo={n:2}?