对象的存储都存堆内存, 在程序中访问和传递, 都按引用值访问和传递, 可类比快捷方式.
实质是一个无序的键值对集合.
创建方式
var obj = {} ;
obj instanceof Object ; // true
var obj2 = new Object({});
obj2 instanceof Object; // true
// 用这种方式会有一点点不一样
var obj3 = Object.create(null);
obj3.__proto__ === undefined; // true
obj3 instanceof Object ; // false
var obj4 = Object.create({});
obj4 instanceof Object; // true
object 拷贝
- 浅拷贝
var obj1 = {name:'xx'}
var obj2 = { ...obj1 }
obj1 === obj2 ; // false
obj1.name = 'kitty';
console.log(obj1); // {name: "kitty"}
console.log(obj2); // {name: "xx"}
// 但是对象里面还有对象就情况不一样了
var obj3 = { data:{name:'xx'}}
var obj4 = {...obj3}
obj3.data.name = 'kitty'
console.log(obj4.data.name); // 'kitty'
- 深拷贝
// 1. 取巧: JSON.parse(JSON.stringify()) 方式
// 最简单偷懒的方式, 但是 obj 存在 Function , RegExp 等时会有一些预料之外的效果
var obj = { data:{name:'xx'}}
var objDeepClone = function(obj){
return JSON.parse(JSON.stringify(obj));
}
var obj1 = objDeepClone(obj)
obj.data.name = 'kitty'
console.log(obj1.data.name); // 'xx'
// 当出现函数和正则表达式时, function 直接丢失了, 正则表达式的值变成 {}
var obj2 = {say:function(){},reg:/\d+/};
objDeepClone(obj2); // {reg:{}}
// 2. 尚未经过大量测试验证可行性
// 大体思路,直到到 基本类型的值的时候, 才开始复制,
// 因为基本类型的复制才是真正的值的复制, 是{} 类型则继续递归
// function(){} , 正则表达式, 数组, 没有做处理,依旧是地址引用
function betterTypeof(data){
return Object.prototype.toString.call(data)
.split(' ')[1]
.replace(/\]/, '');
}
var objDeepClone2 = function (obj) {
var objCopy = {}
Object.keys(obj).forEach((key) => {
var _item = obj[key];
objCopy[key] = (betterTypeof(_item) !== 'Object')
? _item
: objDeepClone(_item)
})
return objCopy
}
// 待续