JS中有5种基本数据类型,它们在赋值的时候是通过值传递,而引用数据类型(对象)是通过引用来传递.
举个例子:
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // 10, 'abc', 5, 'def'
基本数据类型,改变a,b的值并没有影响x,y 当我们使用=
将变量x,y赋值给变量a,b,实际上是将对应的值拷贝了一份,然后赋值给新的变量,这就是值传递.
而对于引用类型:变量赋值是会把引用地址传递过去,而地址指向的是同一块内存的数据,所以改变obj2的值会影响obj1的值.
var obj1 = {name:'yoona'}
var obj2 = obj1
obj2.name = 'jessica'
console.log(obj1.name) // jessica
而且对于引用类型的变量,==
和===
只会判断引用的地址是否相同,而不会判断对象具体里属性以及值是否相同。如果是不同的对象,即使包含相同的属性和值,也会返回false
。
var arrA = ['yoona'];
var arrB = arrA;
console.log(arrA === arrB); // true
var arr1 = ["Jessica"];
var arr2 = ["Jessica"];
console.log(arr1 === arr2); // false
//如果想判断两个不同的对象是否真的相同,一个简单的方法就是将它们转换为字符串然后判断。
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // true
函数传参中的值传递与引用传递:
当我们将基本类型数据传入函数,函数会将这些数据拷贝赋值给函数的参数变量:
function fun(x,y){
return x+y
}
var x = 1
var y = 2
console.log(fun(x,y)) // 3
当我们把对象传入函数,实际上是把对象的引用传递给参数变量.
var a = { age: 10 }
function fn(obj) {
obj = { age: 18 }
return obj
}
var b = fn(a)
console.log(a.age) // 10 这里a的值并没有被改变
console.log(b.age) // 18
// 相当于
var a = { age: 10 }
function fn(obj) {
obj = new Object() // 这个时候 obj的引用地址指向新的内存数据 不再和a指向同一个
obj.age = 18
return obj
}
var b = fn(a)