变量、作用域和内存问题 (二)

时间:2023-02-04 06:10:56

  上一篇文章主要总结了在js中动态为对象添加属性,对象的名字其实是指向对象的指针,在复制的时候,传递是引用这和基本数据类型有所不同。但是即便如此,在js中的函数的参数,不管是什么时候,传递的都是值,也就是说即使函数的参数是一个对象,也是按照值进行传递的,下面就主要说明这个问题。

  先从最简单的来说,函数的参数是一个基本类型的值:

var test=20;
var result=increase(test);
console.log(test);
//输出的结果为20
console.log(result);//输出的结果为40
function increase(num){
num
=num+20;
return num;
}

test是一个基本类型作为函数increase的参数,定义它的值为20,increase函数中的操作是给参数加20然后返回该参数的值,就像最终看到的结果那样,函数返回的结果虽然是40,但是并没有改变参数test的值。所以首先确定的是在函数的参数中基本类型的数据依旧是传值的。

  再看下面的这个例子:

var person=Object();
person.name
="your name";
change(person);
console.log(person.name);
//这里输出的是another name
function change(obj){
obj.name
="another name";
}

在函数change中以对象person作为形参,并修改他的值,然而,在执行完change函数中,发现person中的属性值是变了的,我去,不是说函数中的参数是传值的么?其实,上面的这个看似传了对象的引用的例子,实际上还是传了对象的值,但是表现出了传引用的样子,好像有点绕2333,因为在上一篇中也说过,对象在堆中是唯一的,不同的变量是对对象的不同引用,其实就是不同的指针,但是指向的是在堆中的同一个对象,所以即使在函数的参数中传递的是值,也只是多了一个指向堆中对象的指针,在指向同一对象的所有指针中,任意一个指针对对象的改变都是彻底的同步的。

  如果对函数的参数是对象时传递的是值这个观点有质疑,下面有个例子:

var person=Object();
person.name
="your name";
change(person);
console.log(person.name);
//这里输出的是your name,不会改变
function change(obj){
var newObj=Object();
newObj.name
="another name";
obj
=newObj;
}

同样是change函数以对象person作为参数,但在函数里是对整个参数对象整体的改变,如果说按照传引用的观点来说,在函数change中对参数obj的改变会影响到person,但实际上person的值没有跟着obj的变化而变化。

综上所述,不管js中的函数的参数是什么,传的都是值。