ES6 之 对象属性的可枚举性和遍历

1.Object.getOwnPropertyDescriptor()

解释:获取对对象属性的描述对象。数组

let obj = { foo: 123 };
console.log(Object.getOwnPropertyDescriptor(obj, 'foo'))

显示结果:函数

{
    configurable: true
    enumerable: true
    value: 123
    writable: true
    __proto__: Object
}

enumerable属性,称为可枚举性,若是为 false 时,就表示某些操做会忽略当前属性。this

目前,有四个操做会忽略enumerable为 false 的属性。spa

  • for...in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的全部可枚举的属性的键名。使用这个遍历对象!
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性
Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable // false 
 
Object.getOwnPropertyDescriptor([], 'length').enumerable // false

// toString和length属性的enumerable都是false,所以for...in不会遍历到这两个继承自原型的属性。

2. Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors 方法,返回指定对象全部自身属性(非继承属性)的描述对象。

const obj = {   foo: 123,   get bar() { return 'abc' } }; 
 
Object.getOwnPropertyDescriptors(obj) 

// { foo: 
//    { value: 123, 
//      writable: true, 
//      enumerable: true, 
//      configurable: true }, 
//   bar: 
//    { get: [Function: bar],
//      set: undefined, 
//      enumerable: true, 
//      configurable: true } }

上面代码中,Object.getOwnPropertyDescriptors(obj)方法返回一个对象,全部原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。prototype

 

3. Object.setPrototypeOf()

用于设置一个对象的原型对象。

// 格式 
Object.setPrototypeOf(object, prototype) 
 
// 用法 
const o = Object.setPrototypeOf({}, null); 

// 该方法等同于下面的函数。
function (obj, proto) {   
    obj.__proto__ = proto;   
    return obj; 
}

例子:code

let proto = {}; 
let obj = { x: 10 }; 
Object.setPrototypeOf(obj, proto); 
 
proto.y = 20;
proto.z = 40; 
 
obj.x // 10 
obj.y // 20 
obj.z // 40

注意:对象

  1. 若是第一个参数不是对象,会自动转为对象。可是因为返回的仍是第一个参数,因此这个操做不会产生任何效果。blog

  2. 因为undefined和null没法转为对象,因此若是第一个参数是undefined或null,就会报错。继承

4. Object.getPrototypeOf()

该方法与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象。

Object.getPrototypeOf(obj); 
  1. 若是参数不是对象,会被自动转为对象。ip

  2. 若是参数是undefined或null,它们没法转为对象,因此会报错。

5. super关键字

咱们知道,this关键字老是指向函数所在的当前对象,ES6 又新增了另外一个相似的关键字super,指向当前对象的原型对象

const proto = {   foo: 'hello' }; 
 
const obj = {   
    find() {     
        return super.foo;   
    } 
}; 

Object.setPrototypeOf(obj, proto);
obj.find() // "hello" 
// 上面代码中,对象obj的find方法之中,经过super.foo引用了原型对象proto的foo属性。

注意,super关键字表示原型对象时,只能用在对象的方法之中,用在其余地方都会报错。

JavaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(方法)。

例题:

const proto = {   
    x: 'hello',   
    foo() {     
        console.log(this.x);   
    }, 
}; 
 
const obj = {   
    x: 'world',   
    foo() {    
        super.foo();   
    } 
} 
 
Object.setPrototypeOf(obj, proto); 
 
obj.foo() // "world" 

// 上面代码中,super.foo指向原型对象proto的foo方法,可是绑定的this却仍是当前对象obj,所以输出的就是world。

 

6. Object.keys(),Object.values(),Object.entries()

Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)全部可遍历(enumerable)属性的键名。

var obj = { foo: 'bar', baz: 42 }; 
Object.keys(obj) // ["foo", "baz"] 

 

ES2017 引入了跟Object.keys配套的Object.valuesObject.entries,做为遍历一个对象的补充手段,供for...of循环使用

Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)全部可遍历(enumerable)属性的键值。

const obj = { 100: 'a', 2: 'b', 7: 'c' }; 
Object.values(obj) // ["b", "c", "a"] 

上面代码中,属性名为数值的属性,是按照数值大小,从小到大遍历的,所以返回的顺序是b、c、a。

Object.values只返回对象自身的可遍历属性。

 

Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)全部可遍历(enumerable)属性的键值对数组。

const obj = { foo: 'bar', baz: 42 }; 
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]

除了返回值不同,该方法的行为与Object.values基本一致。

相关文章
相关标签/搜索