JavaScript引用值类型和传递参数问题

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript引用值类型和传递参数问题相关的知识,希望对你有一定的参考价值。

javascript引用值类型和传递参数问题

在我看来也就是作用域的问题
引用类型值指那些可能由多个值构成的对象。

	var person = new Object();
    person.name = 'niupeng';
    console.log(person.name);//niupeng

引用类型的值是按引用访问的“比如我想了解一个人,就去了解这个人的名字,这个人的性别等等”即操作的一般是对象的引用,但是在为对象添加属性时,操作的是实际对象

以上代码创建了一个对象并将其保存在了变量 person 中。然后,我们为该对象添加了一个名为 name的属性,并将字符串值"Nicholas"赋给了这个属性。
紧接着,又通过console.log(person.name);函数访问了这个 新属性。如果对象不被销毁或者这个属性不被删除,则这个属性将一直存在。

传递参数

在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用 ECMAScript 的概念来说,就是 arguments 对象中的一个元素)。在向参数传递引用类型的值时,会把 这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部
也就是说其他基本类型参数的传递不会影响外部的实际值,但是引用值会在函数内部把外部的一起变化
例如:

	function setName(obj)
        obj.name = 'niupeng';
    
    var person = new Object();
    setName(person);
    console.log(person.name);//niupeng
  • 以上代码中创建一个对象,并将其保存在了变量 person 中。然后,这个变量被传递到 setName() 函数中之后就被复制给了 obj
  • 在这个函数内部,objperson 引用的是同一个对象。换句话说,即 这个变量是按值传递的,obj 也会按引用来访问同一个对象。
  • 于是,当在函数内部为 obj 添加 name 属性后,函数外部的 person 也将有所反映;因为 person指向的对象在堆内存中只有一个,而且是全局对象。

会有很多同学错误地认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明 参数是按引用传递的。为了证明对象是按值传递的,我们再看一看下面这个经过修改的例子:

	function setName(obj)  
		obj.name = "Nicholas"; 
		obj = new Object(); 
		obj.name = "Greg";
	
	var person = new Object();
	setName(person);
	alert(person.name);    //"Nicholas"
  • 这个例子与前一个例子的唯一区别,就是在 setName()函数中添加了两行代码:一行代码为 obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的 name 属性。
  • 在把 person 传递给 setName()后,其 name 属性被设置为"Nicholas"。然后,又将一个新对象赋给变量obj,同时将其 name 属性设置为"Greg"
  • 如果 person 是按引用传递的,那么 person 就会自动被修改为指向其 name 属性值 为"Greg"的新对象。

但是,当接下来再访问 person.name 时,显示的值仍然是"Nicholas"。这说明 即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这 个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

以上是关于JavaScript引用值类型和传递参数问题的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 参数传递与变量复制

JavaScript高级 面向对象(12)--引用类型值类型作为参数传递的特性

JavaScript 是按引用传递还是按值传递语言?

js函数中参数的传递

JavaScript高级程序设计(复制变量值传递参数)

基本类型引用类型的复制传递参数