js数据类型
- 基本数据类型(存放在栈空间)
- 引用数据类型(存放在堆空间)
js里面的对象是引用类型,我们在把变量a赋值给变量b的时候,赋值过去的其实是a的引用地址,b有了相同的引用地址,那a跟b指向的都是同一块内存空间,操作b的属性,其实就是操作了这块内存,因为a也指向这块内存,所以a的属性也变了。这其实就是一个浅拷贝。 - 拷贝的栈中的地址。修改拷贝后的数据,原数据会改变
- 拷贝的是堆中的数据。
浅拷贝
方式1: 遍历
let target = {
name: 'John',
age: 20,
friend: {
name: 'lee',
age: 30
}
}
const shallowCopy = (obj) => {
// 判断参数是数组还是对象
const result = Array.isArray(obj) ? [] : {};
for (let key in obj) {
// 使用hasOwnProperty来判断是否是自身属性
// 只拷贝自身属性,不拷贝原型链上的属性,即继承属性
if (obj.hasOwnProperty(key)) {
result[key] = obj[key];
}
}
return result;
}
let newObj = shallowCopy(target);
newObj.age = 50;
console.log(target.age, newObj.age); //20, 50
方式2:
ES6: Object.assign()
let target = {
name: 'John',
age: 20,
friend: {
name: 'lee',
age: 30
}
}
const newObj=Object.assign({},target)
newObj.friend.name = 'baba'
console.log(newObj); //{ name: 'John', age: 20, friend: { name: 'baba', age: 30 } }
方式3: 扩展运算符...
let target = {
name: 'John',
age: 20,
friend: {
name: 'lee',
age: 30
}
}
let newObj ={...target}
newObj.friend.age = 18
console.log(newObj) //{ name: 'John', age: 20, friend: { name: 'lee', age: 18 } }
深拷贝
方式1:
序列化与反序列化
var obj = {
name: "jack",
age: 18,
hobby: ["sing", 'dance']
}
// :
var str = JSON.stringify(obj)
var o = JSON.parse(str)
o.hobby[0] = 'code'
console.log(o); //{ name: 'jack', age: 18, hobby: [ 'code', 'dance' ] }
console.log(obj);//{ name: 'jack', age: 18, hobby: [ 'sing', 'dance' ] }
方式2:
引入loadsh.js
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js">
</script>
var obj = {
name: "jack",
age: 18,
hobby: ["sing", 'dance']
}
let o = _.cloneDeep(obj)
o.hobby[0] = 'code'
console.log(o);
console.log(obj);
方式3:
引入underscore.js,这个库里有一个pick函数
可以实现深拷贝
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.2/underscore-min.js"></script>
let obj = {
name: 'Jhon',
age: 25
}
let age = _.pick(obj, 'age');
console.log(age); // {age: 25}
方式4:
递归遍历
var oldObj = {
name: "Baba",
age: 20,
weather: {
today: "sun",
tomorrow: "rain"
}
}
var newObj = {};
function deepClone(newObj, oldObj) {
for (let k in oldObj) {
let el = oldObj[k];
if (el instanceof Array) {
newObj[k] = [];
deepClone(newObj[k], el);
} else if (el instanceof Object) {
newObj[k] = {};
deepClone(newObj[k], el);
} else {
newObj[k] = el;
}
}
return newObj;
}
newObj = deepClone(newObj, oldObj);
console.log(deepClone);
console.dir(deepClone);
console.log("-----------------------------");
newObj.say = "我是新对象:怎么呢?";
newObj.weather.today = "我是新对象:怎么呢?";
console.log(newObj);
console.log(oldObj);