鍍金池/ 問答/HTML/ 由面試經(jīng)常問的對象賦值引發(fā)的思考

由面試經(jīng)常問的對象賦值引發(fā)的思考

1.

var a = 1;
var b = a;
a = 2;
console.log(b); // 1

var c = [1,2,3];
var d = c;
c.shift();
console.log(d); // [2,3]

我們知道基本對象的賦值是拷貝值,所以改變a不影響b,復(fù)雜對象賦值拷貝的是指針,所以改變c影響d

2.
但是現(xiàn)在有一些奇怪的現(xiàn)象

var a = [1,2,3];
var b = a;
a = [1,2,3,4];
console.log(b); // [1,2,3]

在這里改變了a 但是b沒有改變,并不知道這中間發(fā)生了什么,難道又開辟了一個地址a存放[1,2,3,4]?b還是指向之前的a?

3.

var factorial = function() {
  return 1
};
var trueFactorial = factorial;
factorial = function () {
  return 2;
}
console.log(trueFactorial()); // 1

哎 奇怪了,不是對factorial 重新賦值了嗎?function的賦值不是淺拷貝嗎?

4.

var factorial = function() {
  return factorial();
};
var trueFactorial = factorial;
factorial = function () {
  return 2;
}
console.log(trueFactorial()); // 2

哎 在這里能正常調(diào)用到第二次賦值的那個函數(shù)

回答
編輯回答
夕顏

2,a = [1,2,3,4];創(chuàng)建了一個新的數(shù)組對象,然后把a指向它
3,var trueFactorial = factorial;factorial指向的對象賦值給trueFactorial,所以trueFactorial指向的是最初聲明的方法

2017年6月26日 12:31
編輯回答
憶往昔

復(fù)合類型(Function、Object 等)的賦值是引用傳遞,他們都指向了同一個內(nèi)存地址,

// a變量現(xiàn)在存了一個數(shù)組的內(nèi)存塊地址在棧內(nèi)。
// a變量本身也需要一個內(nèi)存塊存放數(shù)組的地址
var a = [1, 2, 3, 4];

// a把地址傳給了b,b現(xiàn)在也指向了 [1,2,3,4]。
// a和b沒啥關(guān)系,只是指向同一個堆內(nèi)存塊而已
var b = a;

// a變量被重新賦值,a的內(nèi)存塊中存放的地址發(fā)生變化,不再指向原來的數(shù)組
a = [5,6,7];

// a被重新賦值并不會改變b的指向,因為二者在棧內(nèi)是不同的內(nèi)存塊
console.log(b); // [1,2,3,4]

歡迎拍磚?。?/p>

2017年2月25日 23:50
編輯回答
落殤
{
    "type": "Program",
    "start": 0,
    "end": 41,
    "body": [
        {
            "type": "VariableDeclaration",
            "start": 0,
            "end": 16,
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "start": 4,
                    "end": 15,
                    "id": { "type": "Identifier", "start": 4, "end": 5, "name": "a" },
                    "init": {
                        "type": "ArrayExpression",
                        "start": 8,
                        "end": 15,
                        "elements": [
                            { "type": "Literal", "start": 9, "end": 10, "value": 1, "raw": "1" },
                            { "type": "Literal", "start": 11, "end": 12, "value": 2, "raw": "2" },
                            { "type": "Literal", "start": 13, "end": 14, "value": 3, "raw": "3" }
                        ]
                    }
                }
            ],
            "kind": "var"
        },
        {
            "type": "VariableDeclaration",
            "start": 17,
            "end": 27,
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "start": 21,
                    "end": 26,
                    "id": { "type": "Identifier", "start": 21, "end": 22, "name": "b" },
                    "init": { "type": "Identifier", "start": 25, "end": 26, "name": "a" }
                }
            ],
            "kind": "var"
        },
        {
            "type": "ExpressionStatement",
            "start": 28,
            "end": 41,
            "expression": {
                "type": "AssignmentExpression",
                "start": 28,
                "end": 41,
                "operator": "=",
                "left": { "type": "Identifier", "start": 28, "end": 29, "name": "a" },
                "right": {
                    "type": "ArrayExpression",
                    "start": 32,
                    "end": 41,
                    "elements": [
                        { "type": "Literal", "start": 33, "end": 34, "value": 1, "raw": "1" },
                        { "type": "Literal", "start": 35, "end": 36, "value": 2, "raw": "2" },
                        { "type": "Literal", "start": 37, "end": 38, "value": 3, "raw": "3" },
                        { "type": "Literal", "start": 39, "end": 40, "value": 4, "raw": "4" }
                    ]
                }
            }
        }
    ],
    "sourceType": "script"
}

這個就是你要的程序。請分清賦值語句做了什么。賦值語句會更改Identifier的值。pop語句算是一個成員方法,不會改變Identifer的指向。

2018年7月1日 13:28