为什么如果我将对象设置为新变量,它会保存变量的初始值?

Shi*_*e93 8 javascript

我发现JavaScript的一些奇怪的行为,将变量作为参数传递给函数,这里是片段:

var notWorks = {
    aa: "string",
}

function why() {
    var thisWorks = notWorks;
    $.get("/echo/json").then(function() {
        printVal(notWorks);
        printVal(thisWorks);
    });
    notWorks = {};
}

function printVal(val) {
    console.log(val);
}
why();
Run Code Online (Sandbox Code Playgroud)

输出是:

Object {  }
Object { aa: "string" }
Run Code Online (Sandbox Code Playgroud)

对于变量notWorks,一切都很清楚 - 当变量已经被清除时,调用then()中的函数.但是为什么如果我将这个对象设置为一个新变量,它会保存变量的初始值?对象通过链接传递给功能,不是吗?

举例说明:https://jsfiddle.net/cev8m79y/

T.J*_*der 11

变量notWorks一切都清楚了 - then()当变量已被清除时调用函数.

是.

但是为什么如果我将这个对象设置为一个新变量,它会保存变量的初始值?对象通过链接传递给功能,不是吗?

这一行:

var thisWorks = notWorks;
Run Code Online (Sandbox Code Playgroud)

复制参考从物体notWorksthisWorks.此时变量之间没有持续的连接,它们只是引用同一个对象.

然后启动get,并设置notWorks为引用一个新的空白对象.thisWorks仍然指的是前一个对象.因此,当get稍后完成并且同时记录它们时,您会看到thisWorks仍然指向原始对象并notWorks仍指向新的空白对象.

让我们抛出一些ASCII-Art(好吧,技术上它是Unicode-Art):

我们从这开始:

notWorks: Ref11232???+
                     |
                     |
                     |
                     |
                     |  +??????????????+
                     |  |   (object)   |
                     |  +??????????????+
                     +?>| aa: "string" |
                        +??????????????+

("Ref11232"只是对象引用值的占位符.我们实际上从未看到对象引用的值,但您可以将其视为一个数字,告诉JavaScript引擎对象在内存中的位置.)

然后,通过以下方式why创建一个新变量:thisWorksvar thisWorks

notWorks: Ref11232???+
                     |
                     |
                     |
                     |
                     |  +??????????????+
                     +?>|   (object)   |
                        +??????????????+
                        | aa: "string" |
                        +??????????????+
thisWorks: undefined

然后将其设置为与notWorksvia 相同的值thisWorks = notWorks:

notWorks: Ref11232???+
                     |
                     |
                     |
                     |
                     |  +??????????????+
                     +?>|   (object)   |
                     |  +??????????????+
                     |  | aa: "string" |
                     |  +??????????????+
                     |
thisWorks: Ref11232??+

现在他们都指向同一个对象.

然后你开始get,这对那些变量或对象完全没有影响.

然后你给出notWorks一个新值:

notWorks: Ref84325???+
                     |  +??????????????+
                     +?>|   (object)   |
                        +??????????????+
                        |              |
                        +??????????????+

                        +??????????????+
                     +?>|   (object)   |
                     |  +??????????????+
                     |  | aa: "string" |
                     |  +??????????????+
                     |
thisWorks: Ref11232??+

然后等待get完成,然后打印出来.