一、JS的基本数据类型
- 基本数据类型:String,Boolean,Number,Undefined,Null;
- 引用数据类型:Object(Array,Date,RegExp,Function);
- 基本数据类型和引用数据类型的区别:
- 保存位置不同:基本数据类型保存在栈内存中,引用数据类型保存在堆内存中;
- 基本数据类型使用typeof可以返回其基本数据类型,但是NULL类型会返回object,因此null值表示一个空对象指针;引用数据类型使用typeof会返回object,此时需要使用instanceof来检测引用数据类型;
- 定义引用数据类型需要使用new操作符,后面再跟一个构造函数来创建;
1)使用new操作符创建对象;
var obj1 = new Object();
obj1.a = 1;
2)使用对象字面量表示法创建对象;
var obj1 = {
a: 1
}
3)可以通过点表示法访问对象的属性,也可以使用方括号表示法来访问对象的属性;
4.基本类型与引用类型最大的区别实际就是传值与传址的区别:
1)值传递:基本类型采用的是值传递。
2)地址传递:引用类型则是地址传递,将存放在栈内存中的地址赋值给接收的变量。
堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。(引用类型:Function,Array,Object);
优点:存取速度比堆快,仅次于直接位于CPU中的寄存器,数据可以共享;
缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区。
- 浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,指向同一个内存,只是拷贝了引用的地址,当改对象发生改变,拷贝的对象也随之发生改变。
- 深拷贝:深拷贝就是完完整整的将一个对象从内存中拷贝一份出来,拷贝出来的内存和原对象内存的指向都是不同的,修改不会相互影响。
1. for循环:
let arr1 = [1,2,3];
let arr2 = [];
for(let i=0,length=arr.length;i<length;i++){
arr2 .push(arr[i]);
}
2..es6中扩展运算符:
let arr1 = [1,2,3];
let [...arr2] = arr1;
3.Array.from :
let arr1 = [1,2,3];
let arr2 = Array.from(arr1);
注意:slice()和concat()都并非深拷贝。
对象的深拷贝:
1.for循环:
let obj1={count:1,name:'grace',age:1};
let obj2 = copyObj(obj){
let res = {};
for(let key in obj){
res[key]=obj[key];
} return res;
}
2.利用JSON:
let obj1={count:1,name:'grace',age:1};
let obj2 = JSON.parse(JSON.stringify(obj1));
3.扩展运算符:
let obj1={count:1,name:'grace',age:1};
let {...obj2} = obj1;
4.Object.assign()实现浅拷贝及一层的深拷贝
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
写的不足,欢迎大家吐槽!