1、Object.getPrototypeOf(obj)
该方法返回 obj 对象的原型对象,等同于 obj.__proto__。获取对象的原型对象推荐使用该方法而不是 obj.__proto__方法
function Person(){ this.name = 'jack' } let man = new Person(); console.log(Object.getPrototypeOf(man) === Person.prototype); //true console.log(Object.getPrototypeOf(man) === man.__proto__); //true
2、Object.defineProperty()
该方法会直接在一个对象上添加一个新属性,或者修改一个对象的现有属性, 并返回该对象。
Object.defineProperty(obj, prop, descriptor); //obj:要修改的对象 prop:要添加或修改的属性的名称。 descriptor:属性描述符。
let obj = {}; Object.defineProperty(obj, "key", { enumerable: false, configurable: false, writable: false, value: "static" });
数据描述符和存取描述符均具有以下可选键值:
- configurable:仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false
- enumerable: 仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false
- value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
- writable: 仅当仅当该属性的writable为 true 时,该属性才能被赋值运算符改变。默认为 false
- get:给属性设置 getter,在读取属性时将会调用该方法,默认值是undefined,该方法的返回值将被用作属性值。
- set:给属性设置 setter,在写入属性的时候调用该方法,默认是undefined。该方法将接受唯一参数,并会自动将该参数的新值分配给该属性。
2.1、set和get方法同时存在时的问题及解决
当通过 Object.defineProperty() 来给一个对象的属性设置 getter 和 setter 时,如下:
let data = {} Object.defineProperty(data,'name',{ // 访问name属性就会执行此方法 返回值就是属性值 get(){ console.log('name属性被获取了') return '柴柴老师' }, // 设置新值就会执行此方法 set(newVal){ console.log('name属性被设置新值了') console.log(newVal) } }) console.log('初始化值', data.name); data.name = 'new Name'; console.log('修改后的值', data.name);
输出结果如下:
可以看到,此时设置对象属性值,实际上并没有修改到对象的属性的值。这是因为 get 和 set 并没有关联起来,get 返回的值都是固定的,不会随着 set 的设置而改变。
此时我们可以简单地通过一个临时变量解决这个问题,如下:
let _name = '柴柴老师'; let data = {} Object.defineProperty(data,'name',{ // 访问name属性就会执行此方法 返回值就是属性值 get(){ console.log('name属性被获取了') return _name }, // 设置新值就会执行此方法 set(newVal){ console.log('name属性被设置新值了') console.log(newVal) _name = newVal } }) console.log('初始化值', data.name); data.name = 'new Name'; console.log('修改后的值', data.name);
输出结果如下:
3、Object.assign()
该方法用于将一个或多个源对象的所有可枚举属性的值复制到目标对象。它将改变目标对象然后返回目标对象。
Object.assign(target, source1, source2) //target:目标对象 source1、source:源对象
如果目标对象和源对象中的属性名重复,那么源对象将覆盖掉目标对象的属性值,后面的源对象将覆盖前面的源对象。
该方法是浅拷贝。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。
let obj1 = { a: 0, b: { c: 0 } }; let obj2 = Object.assign({}, obj1); console.log(obj2); // { a: 0, b: { c: 0}} obj1.a = 1; obj1.b.c = 3; //当源对象的属性值是一个对象时,改变该属性,目标对象也随之改变 console.log(obj1); // { a: 1, b: { c: 3}} console.log(obj2); // { a: 0, b: { c: 3}}
可以利用JSON对象方法实现深拷贝
let obj1 = { a: 0, b: { c: 0 } }; let obj2 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; //此时改变obj1属性的值,obj2不会随之改变 console.log(obj2); // { a: 0, b: { c: 0}}