1. 如何定义一个对象
ES6之前
| var a = new Object() |
| var a = {} |
这两种定义对象是有原型链存在,并可以使用原型链上方法如toString()等
ES6新增另外一种
| var b=Object.create() |
| |
| b.toString() |
这种方法定义对象,是不存在原型的,里面就真的啥方法都没有,空空如也。
2. 对象如何获取变量key
ES6之前
| var name='a' |
| var object={} |
| object[name]=1 |
| console.log(object) |
ES6修改成
| var name='a' |
| var object={[name]:1} |
| console.log(object) |
3. 对象属性定义
ES6之前
| var o = { |
| a: a, |
| b: b, |
| c: c |
| }; |
| |
| var o={ |
| sayHi:function(){} |
| } |
ES6修改成
| var o = {a, b, c}; |
| |
| var o={ |
| sayHi(){} |
| } |
4. ES6对象新增了getter和setter方法
| var o={ |
| _age:18, |
| get age(){return o._age}, |
| set age(value){if(value<100){o._age=value}else{o._age=100}} |
| } |
调用o.age就相当调用了getter方法,调用o.age=1000就相当调用了setter方法。ES6使得对象属性可以自行定义获取和设置。
5. 对象的浅拷贝(两个地址不一样的对象)
ES6之前
| var obj1={a:1,b:2,c:3} |
| var obj2={} |
| for(let key in obj1){ |
| obj2[key]=obj1[key] |
| } |
| console.log(obj2) |
不包含函数的对象
对于不包含函数的简单对象,可以用JSON.stringify()
和JSON.parse()
方法来进行对象的深拷贝(对象中含有其他简单对象也可以)。
注意:这种不是浅拷贝,修改obj2会导致obj1也会变
| var obj1={a:1,b:2,c:3} |
| obj2= obj1 |
ES6新增
(1) Object.assign()方法
| var obj1={a:1,b:2,c:3} |
| var obj2=Object.assign({},obj1) |
| console.log(obj2) |
(2) 用剩余参数方法
| var obj1={a:1,b:2,c:3} |
| var obj2={...obj1} |
| console.log(obj2) |
6. 对象的原型
| var a={} |
| |
| a.__proto__===Object.prototype |
如何修改对象原型
| var b={ |
| sayHi(){ |
| console.log('hi') |
| } |
| } |
| |
| a=Object.create(b) |
| |
| a.__proto__===b |
如何找出对象原型
a.__proto__
Object.getPrototypeOf(a)
6. 属性修饰符
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
对象的深拷贝
简易深拷贝
我先写了个简单的对象深拷贝函数,不考虑循环引用问题。
| const _sampleDeepClone = target => { |
| |
| let ans = {}; |
| for(let key in target){ |
| if(target[key] instanceof Array){ |
| ans[key] = [...target[key]]; |
| }else if(typeof target[key] === 'object' && target[key] != null){ |
| ans[key] = _sampleDeepClone(target[key]); |
| }else{ |
| ans[key] = target[key]; |
| } |
| } |
| return ans; |
| } |
包含循环引用的对象的深拷贝
| export const deepClone = (obj, hash = new WeakMap()) => { |
| |
| if (target === null || typeof target !== 'object'){ |
| return target; |
| } |
| |
| if (obj instanceof Date){ |
| return new Date(obj); |
| } |
| |
| if (obj instanceof RegExp){ |
| return new RegExp(obj); |
| } |
| |
| if (hash.has(obj)){ |
| return hash.get(obj); |
| } |
| |
| let allDesc = Object.getOwnPropertyDescriptors(obj); |
| |
| let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc); |
| |
| hash.set(obj, cloneObj) |
| for (let key of Reflect.ownKeys(obj)) { |
| if(typeof obj[key] === 'object' && obj[key] !== null){ |
| cloneObj[key] = deepClone(obj[key], hash); |
| } else { |
| cloneObj[key] = obj[key]; |
| } |
| } |
| return cloneObj |
| } |
知识点补充
包含循环引用的对象
深拷贝一个包含循环引用的 JavaScript 对象需要特殊处理。循环引用是指对象属性之间存在相互引用的情况,导致深拷贝时陷入无限循环的问题。如: obj1.self = obj1; // 添加循环引用
WeakMap
WeakMap
是 JavaScript 的内置对象,它是一种弱引用的映射结构。WeakMap
可以用来存储键值对,其中键是对象,值可以是任意类型的值。与Map
不同,WeakMap
中的键是弱引用的,这意味着当键对象没有其他引用时,它们可能会被垃圾回收机制回收,并从WeakMap
中自动移除。
Comments NOTHING