ES6学习笔记(二) --- 一探Object.create和对象属性操作符

236 阅读3分钟

Object.create

语法参数

Object.create(proto, [propertiesObject])

  • 创建一个对象,并将新对象的__proto__指向 proto
  • propretiesObject为可选对象,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性),将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应的第二个参数。
  • 在指定原型对象上添加新属性后的对象。
let obj = {
    name: 'herry',
};
let obj1 = new Object(obj);
let obj2 = Object.create(obj, {
    name: {
        // 遍历当前对象,是否可以遍历出当前属性  enumerable / configurable / writeable 
        enumerable: true,
        // writable:true,
        configurable: true,
        // value: 'tom',
        get: function(){
            console.log('getting tom');
        },
        set: () => {
            console.log( 'setting tom' );
        }
    },
    age: {
        writable: true,
        enumerable: false,
        value: 20
    }
});
console.log( obj1 );
console.log( obj2 );

Object.create()new Object的区别

创建对象的方式不同

  • new Object(obj)创建对象,所添加的属性都是其自身实例的属性。
  • Object.create(obj,[propertiesObject] ) 是将创建的对象__proto__指向obj,其实例可以继承obj属性。可以通过第二个参数添加其实例自身属性。
  • 代码示例如上。

属性描述符默认值不同

  • Object.create()第二个参数来创建非空对象的属性描述符默认为false,而构造函数或字面量方法创建的对象属性的描述符默认为true。

拓展

对象属性操作符

  • getOwnPropertyDescriptor(obj, key) 获取对象自身某一属性的描述符

  • getOwnPropertyDescriptors(obj) 获取一个对象自身所有的描述符

  • defineProperties(obj, props) 在一个对象上定义新的属性或修改现有属性,并返回该对象

  • defineProperty(obj, key, descriptor) 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性

  • getOwnPropertyNames(obj) 查找对象不包括Symbol类型的所有的属性名

  • getOwnPropertySymbols(obj) 查找对象所有的Symbol类型的属性名

  • hasOwnProperty(key) 对象自身是否含有指定的属性

    代码示例:

"use strict";
let adress = Symbol('address');
let phone = Symbol('phone');
let obj = {
    name: 'jerry',
    age: 18,
    [adress]: 'shenzhen',
    [phone]: '123456789',
}
Object.getOwnPropertyNames( obj );   // => ['name', 'obj']
Object.getOwnPropertySymbols(obj); // => [ Symbol('address'), Symbol('phone') ]
Object.getOwnPropertyDescriptor(obj, 'name');  // => { writable: true, configurable: true, enumerable: true, value: 'jerry' }
Object.getOwnPropertyDescriptors( obj ); // => { name: { writable: true, configurable: true, enumerable: true, value: 'jerry' } , age: { ... }}
Object.hasOwnProperty('name'); // => true
Object.defineProperty(obj, 'age', {
    writable: false
});
Object.defineProperties(obj, {
    name: {
        enumerable: false
    }
});
// obj.age = 20;  // TypeError  //已设置只读属性
for (const key in obj) {
    // for in 不会遍历出 Symbol 类型 以及 操作符 enumerable  为 false 的属性
    console.log( key );  // age
}

小思考,输出什么?:

const person = { name: "Lydia" };

Object.defineProperty(person, "age", { value: 21 });

console.log(person);
console.log(Object.keys(person));

更改对象原型

  • Object.create(obj, [propertiesKey] )
  • Object.setPrototypeOf(obj1, obj2 ) // 将obj2设置为obj1的原型

读取对象原型

  • Object.getPrototypeOf(obj)

判断是否是原型

  • Object.prototype.isPrototypeOf(obj)

    代码示例:

let obj1 = { name: '12' };
let obj2 = {};
// 设置 obj1 为 obj2 的原型
Object.setPrototypeOf(obj2, obj1);
// 获取obj2的原型
Object.getPrototypeOf( obj2 );
// 判断obj1是不是obj2的原型
obj1.isPrototypeOf( obj2 );

冻结对象

  • Object.freeze(obj || arr ) <=> Object.isFrozen(obj);
  • 操作符和属性、原型都不可以修改
  • freeze() 返回和传入的参数相同的对象。
  • 不能添加 不能删除 不能修改

密封对象

  • Object.seal(obj) <=> Object.isSealed(obj);
  • 封闭一个对象,阻止添加新属性,不可删除属性、并将所有现有属性标记为不可配置。
  • 当前属性的只要可写(writable === true),其值就可以被更改。
  • 不能添加 不能删除 能修改

可拓展

  • Object.preventExtensions(obj) <=> Object.isExtensible(obj);
  • Object.freeze Object.seal Object.preventExtensions 都可以标记一个对象为不看拓展。
  • 让一个对象变的不可扩展,不能再添加新的属性,可修改和删除已有的属性。
  • 不能添加 能删除 能修改

迭代操作

  • Object.keys()
  • Object.values()
  • Objecr.entries()

对象同等

  • Object.is()

相关文章:

1. ES6学习笔记(一)

参考资料:

1. Object.create()

2. Object.create() - JavaScript | MDN