- 基本类型值(数值、布尔值、字符串、null和undefined):指的是保存在栈内存中的简单数据段;
- 引用类型值(对象、数组、函数、正则):指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象
复制变量值
基本类型
除了保存方法不同之外,基本类型和引用类型在复制的时候也有很大的不同。
如果是从一个变量向另一个变量复制基本类型的值时,会在新的变量上创建一个新值,两个变量是互不影响的
var num1 = 5;
var num2 = num1;
num2 += 5;
console.log(num1);//5
console.log(num2);//10
在复制基本类型的值时,其实是在栈内存中再开辟一个新个空间来存放这个副本,所以它们在进行任何操作时都不会相互影响
引用类型
当一个变量向另外一个变量复制引用类型的值时,本质上复制的只是复制了一个指针,这个指针指向被复制的引用类型在堆内存中的地址,所以这两个变量会互相影响。
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "咸鱼";
console.log(obj2.name);//咸鱼
在这个例子中我们给obj1添加了name属性同时也影响到了obj2了。
对象拷贝
如果我们需要拷贝一个引用类型时候需要一些特殊的方法:
//浅拷贝
function shallowCopy(oldObj) {
var newObj = {};
for(var i in oldObj) {
if(oldObj.hasOwnProperty(i)) {
newObj[i] = oldObj[i];
}
}
return newObj;
}
//深拷贝
function deepCopy(oldObj) {
var newObj = {};
for(var key in oldObj) {
if(typeof oldObj[key] === 'object') {
newObj[key] = deepCopy(oldObj[key]);
}else{
newObj[key] = oldObj[key];
}
}
return newObj;
}
传递参数
(摘录自《JavaScript高级程序设计》)
ECMAScript中的所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从变量复制给另外一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型值的传递,则和引用类型变量的复制一样。有不少开发人员在这一点上可能会有困惑,因为访问变量有按值传递和按引用两种方式,而参数只能按值传递。
function inc(n){
n++;
}
var a = 10;
inc(a);
console.log(a);
function incObj(obj){
//var obj = o //0x0001
obj.n++;
}
var o = {n: 10}; //o = 0x0001
incObj(o);
console.log(o);
function squireArr( arr ){
//var arr = 0x0011
for(var i = 0; i < arr.length; i++){
arr[i] = arr[i] * arr[i];
}
}
function squireArr2( arr ){
var newArr = [];
for(var i = 0; i < arr.length; i++){
newArr[i] = arr[i] * arr[i];
}
return newArr;
}
var arr = [2,1,3,6]; //arr 0x0011
squireArr(arr);
console.log(arr); // [4,1,9,36]
var arr2 = squireArr2(arr)
console.log(arr2);
虽然所以的参数都是按值传递的,但是在传递引用类型的参数时已经会和原始数据互相影响。