[学习笔记] JavaScript - Call by Value vs Call by Reference or Sh

本篇内容参考连结
PJCHENder

Data Type

首先必须了解, 在Javascript中, 有需多资料型别, 主要分成两大类. 分别是基本型别(primitive type)和物件型别(Object).

Primitive type:BooleanNullUndefinedNumberBigIntStringSymbolObject:Array, function, map, ...etc

一般来说, Primitive type会是Call by Value, 而Object则是 Call by Reference. 接下来会用几个程式範例来解释.

Call by Value

直接来看简单的範例, 先建立一个变数 a 并赋予值 3. 再来建立变数 b, 并把b的值等于a. 最后再把 a 的值改成2.

var a = 3;var b;b = a;a = 2;console.log(a);console.log(b);

再来我们看到结果很直观的呈现

a is 2
b is 3

由此可知道当把一个变数等于另一个变数时, 只把值赋予给另一个变数, 之后两者是独立的, 操作并不互相影响. 往更底层去了解的话, 即是当我们在建立 primitive type 的变数时, 会把他存在记忆体的某个地方(假设为 0x001), 而当我们宣告另一个变数, 并把前一个的值赋予给他的时候, 他其实会建立自己的记忆体位址(假设为 0x002). 所以当之后操作的时候, 因为本身就处于不同的记忆体位址, 所以不会互相干扰. 这个就是所谓的 Call by Value.

Call by Value 大部分都会发生在 primitive type 的变数

Call by Value

Call by Reference

直接来看简单的範例, 先建立一个变数 a 并赋予一个Object { text: "Hello"}. 再来建立变数 b, 并把b的值等于a. 最后再把 a 里的Property text的值改成Hi.

var a = { text: "Hello"};var b;b = a;a.text = "Hi";console.log(a);console.log(b);

结果b的值也一起被更新了

{ text: 'Hi' }
{ text: 'Hi' }

当变数为Object时, 赋予给先的变数. 两者会相依, 在之后的操作也会互相影响. 从记忆体的方面来说, 当建立a时, 会存在位址(假设为 0x001). 而当建立b并把a的值赋予b时, 这时候并不会再给他一个新的位址, 而是把b指定到相同位址(0x001). 所以当在操作更改值时, 从变数a或变数b, 其实都是对存在位址0x001的值做操作, 所以才会更改a的时候, b也一起被更新. 这个就是所谓的 Call by Reference.

Call by Reference 大部分都会发生在 Object 的变数

Call by Reference

Call by Reference - Additional Information

等于(== 或是 ===)被用reference type上, 则会比较reference不会是value. 参考以下例子

var a = { text: "Hello"};var b;console.log(a == b); // truevar c = { text: "Hello"};var d = { text: "Hello"};console.log(c == d); // false

所以在比较时, 可以先把其转成primitive type: string

var c = { text: "Hello" };var d = { text: "Hello" };console.log(c == d); // falsevar e = JSON.stringify({ text: "Hello" });var f = JSON.stringify({ text: "Hello" });console.log(e == f); // true

Call by Sharing

这次来看一个比较特别的例子, 对上面call by reference的例子做点修改, 这次不是更新Object里的Property, 而是直接给一个新的Object.

var a = { text: "Hello" };var b;b = a;a = { text: "Hi" };console.log(a);console.log(b);

这次结果则不会一起更新

{ text: 'Hi' }
{ text: 'Hello' }

当Object被重新赋予值时(并非更新Property), 则会记忆体给予一个新个位置. 事实上, Javascript不属于单纯的by value 或是 by Reference. 更準确来说就是Call by sharing. 所以当Object被重新赋值时, 基本上就会跟Pass by Value的结果一模一样. 当Object仅内容被更新时, 则会回到call by reference的结果.


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章