JavaScript 按值传递 & 按引用传递

JavaScript 按值传递 & 按引用传递

(1)值的比较--引用的比较

首先,原始值的比较是值的比较:只有在它们值相等的时候它们才相等

比如简单的

代码语言:javascript代码运行次数:0运行复制var a1 = 10;

var a2 = 10;

console.log(a1 === a2); //true其次,对象的比较并非值的比较:对象的比较均是引用的比较,当且仅当它们引用同一个基对象时,它们才相等。

即使两个对象包含同样的属性和相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不相等

比如

代码语言:javascript代码运行次数:0运行复制var o = {x:1},p={x:1};

console.log(o === p); //false 两个单独的对象不相等

var a = ['you'],b = ['you'];

console.log(a === b); //false 两个单独的数组不相等代码语言:javascript代码运行次数:0运行复制var a = [];

var b = a; // b 引用了同一个数组a

b[0] = "you";

console.log(a[0]); // you 这是a也会修改

console.log(a === b); //true所以,如果我们要得到一个对象或者数组的副本,或者是要比较两个单独对象或数组相等情况,就要比较它们的属性元素等,通过循环遍历数组来实现

(2)按值传递 -- 按引用传递

按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。

按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相同的值

1. JS的基本类型是按值传递的

比如

代码语言:javascript代码运行次数:0运行复制var a = 1;

function foo(a) {

a = 2;

console.log(a); //此副本为2

}

foo(a);

console.log(a); // 仍为1, 未受a = 2赋值所影响

2.但是对象或者数组之类呢?先看个例子

比如

代码语言:javascript代码运行次数:0运行复制var obj = {x : 1};

function foo(o) {

o.x = 3;

console.log(obj.x); // 3, 被修改了!

}

foo(obj);

console.log(obj.x); // 3, 也被修改了!说明o和obj是同一个对象,o不是obj的副本。所以不是按值传递。 但这样是否说明JS的对象是按引用传递的呢?我们再看下面的例子:

比如

代码语言:javascript代码运行次数:0运行复制var obj = {x : 1};

function foo(o) {

o = 100;

}

foo(obj);

console.log(obj.x); // 仍然是1, obj并未被修改为100.如果是按引用传递,修改形参o的值,应该影响到实参才对。但这里修改o的值并未影响obj。

因此JS中的对象并不是按引用传递。那么究竟对象的值在JS中如何传递的呢?

按共享传递 call by sharing

准确的说,JS中的基本类型按值传递,对象类型按共享传递的(call by sharing,也叫按对象传递、按对象共享传递)

该策略的重点是:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。

它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。如上面例子中,不可以通过修改形参o的值,来修改obj的值。

然而,虽然引用是副本,引用的对象是相同的。它们共享相同的对象,所以修改形参对象的属性值o.x=3,也会影响到实参的属性值。

另外一个例子

代码语言:javascript代码运行次数:0运行复制var obj = {x : 1};

obj.x = 100;

var o = obj;

o.x = 1;

obj.x; // 1, 被修改

o = true;

obj.x; // 1, 不会因o = true改变对于对象类型,由于对象是可变(mutable)的,修改对象本身会影响到共享这个对象的引用和引用副本。

而对于基本类型,由于它们都是不可变的(immutable),按共享传递与按值传递(call by value)没有任何区别,所以说JS基本类型既符合按值传递,也符合按共享传递。

相关推荐

软件性能测试报告需要注意哪些点?测试周期需要多久?
365永久激活怎么做到的

软件性能测试报告需要注意哪些点?测试周期需要多久?

📅 08-05 👁️ 938
包含力的字,力部首的字有哪些
365永久激活怎么做到的

包含力的字,力部首的字有哪些

📅 07-18 👁️ 7231
威刚SP800(32GB)
365天电影观看免费

威刚SP800(32GB)

📅 08-19 👁️ 850
如何快速焊接usb接口 usb插头焊接方法?
365永久激活怎么做到的

如何快速焊接usb接口 usb插头焊接方法?

📅 08-08 👁️ 6971
两墯的意思
365永久激活怎么做到的

两墯的意思

📅 07-26 👁️ 6820
抖音帝王套是什么 抖音帝王套介绍
365天电影观看免费

抖音帝王套是什么 抖音帝王套介绍

📅 08-06 👁️ 5610