Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
a.x=a={n:b}在JavaScript中是如何工作的?_Javascript - Fatal编程技术网

a.x=a={n:b}在JavaScript中是如何工作的?

a.x=a={n:b}在JavaScript中是如何工作的?,javascript,Javascript,这是有关的 我明白 foo = foo.x = {n: b}; // console.log(foo) => {n: b} 但是 它应等于: foo = {n: b}; foo.x = foo; // console.log(foo) => {n: b, x:object} 我在这里遗漏了什么吗?它等于 let tmp = foo; foo = {n: b}; tmp.x = foo; 您可以看到,旧的foo(在本例中存储在z中)已被修改: > z=foo={}; {}

这是有关的

我明白

foo = foo.x = {n: b}; // console.log(foo) => {n: b}
但是

它应等于:

foo = {n: b};
foo.x = foo; // console.log(foo) => {n: b, x:object}
我在这里遗漏了什么吗?

它等于

let tmp = foo;
foo = {n: b};
tmp.x = foo;
您可以看到,旧的
foo
(在本例中存储在
z
中)已被修改:

> z=foo={};
{}
> foo.x = foo = {n: b};
{ n: 10 }
> foo
{ n: 10 }
> z
{ x: { n: 10 } }
我明白了

var foo = {}; // now foo is a reference point to object {}
foo.x = foo = {n:1}; // first foo is refer to a new object {n:1}, then old foo referred object {} set a prop x

// try this to get what you want
var foo = foo1 = {};
foo.x = foo = {n:1};
console.log(foo, foo1) // here foo1 is what you want
与:

在继续实际分配之前,首先对前面的
foo.x
进行部分评估,足以确定分配的确切目标

它的行为更符合以下几点:

var oldFoo = foo;
foo = {n: b};
oldFoo.x = foo;

=
的左侧在将值放入(1.f)之前进行计算(1.a):

AssignmentExpression:LeftHandSideExpression=AssignmentExpression

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

f) 表演?PutValue(lref,rval)


这是因为当你写作的时候

var foo = {};
foo.x = foo = {n: b} //a=b=c
当执行该行时,foo指向
{}
,但当该语句分解为

foo.x = (foo = {n: b}) /a=(b=c)
foo的引用已从
{}
更改为
{n:b}
,但
foo.x
(a)中的
foo
(a)仍然指向
foo
的旧引用,因为左手表达式是在作业开始之前评估的

按照

  • 如果LeftHandSideExpression既不是ObjectLiteral也不是 平行排列

    a。然后让lref作为评估的结果 左手边的表情

  • 这意味着在分配之前,
    foo.x
    仍然引用旧的
    foo

    所以,如果你通过这样做稍微调整一下你的例子

    var foo = {z:2};
    foo.x = foo.n = {n: 1};
    
    在本例中,您没有将引用更改为
    foo
    ,只指定了新属性,因此现在输出为

    对象{z:2,n:Object,x:Object}


    现在,它保留了对旧的
    foo
    的引用,因为没有分配新的引用,因此所有属性
    z
    n
    x
    都被保留。

    console.log(foo.x)应该打印出相同的内容。我遇到一个错误“无法设置未定义的属性“x”除非
    foo
    已经引用了某个对象,否则我看不出第一行如何工作。(第二个也是如此,尽管直觉上第二个“感觉”它应该按原样工作。)你说它应该等于什么,没有任何理由。没有理由,因为这句话是假的。你能给我解释一下你为什么相信这个谎言吗?这有助于我理解为什么人们相信编程语言是错误的。其他答案描述了这就是正在发生的事情,但是一个
    tmp
    foo
    的例子一开始就有了与它们的值相同的对象,这就更清楚了。
    foo.x = (foo = {n: b}) /a=(b=c)
    
    var foo = {z:2};
    foo.x = foo.n = {n: 1};