What is binding?
Binding 去查字典是「捆綁、裝訂」的意思,常見的技術翻譯則是「繫結」,他想表達的,就是一種連結關係,連結的是變數名稱與值。Nicholas C. Zakas 替 binding 下了一個定義:
bindings, as a name is bound to a value inside scope
讓我們講白話一點,當變數賦予了值,就是一個 binding 的成立:
1 | var a = 1; |
在 JavaScript 裡,變數名稱與值的連結關係,會存放在 variable object 裡,就像這張圖:
懂了 binding ,就可以來亂聊一些東西。
Types
JS 分成兩種型別: Primitive types 和 Reference types。Primitive 用來存放簡單值,Reference 則是用來存放物件。其他語言使用了 stack 和 heap ,JS 則不太一樣,他使用的是 variable object 的方式。Primitive 值是直接存放在 variable object 裏,Reference 值是把 reference 當作 pointer 一樣,存在 variable object 裏。
如果從人類角度來看,就會發現有趣的事:
1 | var a = 1; |
1 | var obj1 = new MyClass(); |
對照上圖,a 這組 binding 的 value ,是存放人類所看到的「1」,而 obj1 則不是,實在上它存放的是 new MyClass() 這個新物件在記憶體中的位址(reference)。所以,variable object 裡的 value 意義不等同人類所看到的 value。
當我們在做這些事的時候
1 | var c = a; |
1 | var obj2 = obj1; |
其實是把 variable object 的 value 「複製」給新變數。所以 c 有了「1」,obj2 則有了「3AF4」這個位址,obj1 和 obj2 指向了同一個物件。從人類角度,a 和 c 各有一個「1」值,obj1 和 obj2 則是共有一個物件值。
這就不意外做以下的動作,會得出這樣的結果:
1 | a = 2; |
1 | obj1.name = 'two'; |
那讓子彈莫名地掃到 const 吧!
1 | const a = 1; |
obj 不能被改的是 variable object 的 value,還是人類角度的 value 呢?這個問題,就留給看官自行驗證吧!