关于Object属性的一些理解

2018-11-13  本文已影响30人  哇塞田

平时在业务写需求的时候总是会涉及到获取对象属性的需求。比如你可以像下面这么做:

    const obj = {
      prototype1: 1,
      prototype2: null,
      prototype3: 3
    }
    for (let key in obj) {
      console.log(key) // 'prototype1' 'prototype2' 'prototype3'
    }
    Object.prototype.prototype4 = 4
    const obj = {
      prototype1: 1,
      prototype2: null,
      prototype3: 3
    }
    for (let key in obj) {
      console.log(key) // 'prototype1' 'prototype2' 'prototype3' 'prototype4'
    }

所以我们用for in遍历对象的属性的时候需要过滤掉来自于原型链上的属性,hasOwnProperty方法接受一个字符串或者symbol用来返回对象上是否存在该属性,且该方法只会检测自身属性。所以代码可以作如下改造:

    Object.prototype.prototype4 = 4
    const obj = {
      prototype1: 1,
      prototype2: null,
      prototype3: 3
    }
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        console.log(key) // 'prototype1' 'prototype2' 'prototype3'
      }
    }

但是如果你以为这样就安全就太年轻了,因为hasOwnProperty作为对象的一个属性来讲是可以被重写的,所以我们最好不要直接用对象自身的hasOwnProperty,而是如下:

    Object.prototype.prototype4 = 4
    const obj = {
      prototype1: 1,
      prototype2: null,
      prototype3: 3
    }
    for (let key in obj) {
      if (Object.hasOwnProperty.call(obj, key)) {
        console.log(key)
      }
    }
console.log(Object.getOwnPropertyDescriptor(obj, 'prototype1'))

我们可以看到打印了一个对象,其中enumerable为true。其实我们也可以设置对象的属性为不可枚举,然后在用for in看是否可以遍历的到:

    Object.prototype.prototype4 = 4
    const obj = {
      prototype1: 1,
      prototype2: null,
      prototype3: 3
    }
    Object.defineProperty(obj, 'prototype1', {
      enumerable: false
    })
    for (let key in obj) {
      if (Object.hasOwnProperty.call(obj, key)) {
        console.log(key)  // 'prototype2' 'prototype3'
      }
    }

这里我们使用defineProperty去设置对象的属性的属性描述符,该方法第一个参数为对象,第二个参数为对象的属性,第三个参数为属性描述符。我们看到了prototype1没有被遍历到。

上一篇下一篇

猜你喜欢

热点阅读