对于JavaScript中对象参数的传递方式的浅析

本文章主要是想探索一下JavaScript中,对象类型的参数的传递方式

背景:

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

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

let set = new Set();
set.add({t:1});
set.has({t:1}); // false

let set = new Set();
let obj = {t:1};
set.add(obj);
set.has(obj); // ture

通过上面的代码可以显而易见的得出JavaScript中对象类型的参数肯定不是值传递的。实际上,在JavaScript中其它的数据的数据类型(undefinednullBooleanStringNumber)都是按值传递的。

再来看看对象的传递:

var obj = {x : 1};
    function foo(o) {
    o.x = 3;
}
foo(obj);
console.log(obj.x); // 3, 被修改了! 

var obj = {x : 1};
function foo(o) {
    o = 100;
}
foo(obj);
console.log(obj.x); // 仍然是1, obj并未被修改为100.

其实,对象类型的参数是按共享传递的(call by sharing,也叫按对象传递、按对象共享传递)。

该策略的重点是:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。

总结:

基本类型是按值传递,而对于对象来说传入的是对象指向的地址,也可以认为其是特殊的按值传递。如果在函数内对对象的属性进行操作,实际就是对其指向对象的属性进行操作。但是,如果对其整体进行操作(比如:o = 100或者o = []),其实际是新定义了对象,实参的引用地址为新的对象的引用地址,与原来的引用没有任何关系,所以不会对原来的对象造成改变。

拓展:

那么怎么去判断两个对象相等呢?

最简单的办法是使用 JSON.stringify 将对象转换成字符串,然后再进行比较。

参考:

深入浅析JS是按值传递还是按引用传递(推荐)

猜你喜欢

转载自blog.csdn.net/r122555/article/details/80827072
今日推荐