从Vue源码进修JavaScript之Object.defineproperty

Vue内里有个耳熟能详的词是Object.defineproperty,这篇文章就引见一下这个属性。

Object.defineProperty() 要领会直接在一个对象上定义一个新属性,或许修正一个对象的现有属性, 并返回这个对象。

语法

Object.defineProperty(obj, prop, descriptor)

参数

  • obj:要在其上定义属性的对象
  • prop:要定义或许要修正的属性
  • descriptor:将被定义或修正的属性形貌符

descriptor属性形貌符

属性形貌符又可分为数据形貌符和存取形貌符,能够用getOwnPropertyDescriptors或许getOwnPropertyDescriptor获取到属性形貌

数据形貌符和存取形貌符共有的属性包含:

  • configurable

    当且仅当该属性的 configurable 为 true 时,该属性形貌符才够被转变,同时该属性也能从对应的对象上被删除,假如为false,则不能删除或修正writable, configurable, enumerable。默以为 true。

    
    var animal = {
        name: 'cat'
    }
    console.log(Object.getOwnPropertyDescriptors(animal)) 
    //name: {value: "cat", writable: true, enumerable: true, configurable: true}
    console.log(animal.name) //cat
    delete animal.name
    console.log(animal.name) //undefined
    
    Object.defineProperty(animal, 'name', {
        value: 'dog',
        configurable: false
    })
    console.log(Object.getOwnPropertyDescriptors(animal))
    //name: {value: "dog", writable: false, enumerable: false, configurable: false}
    console.log(animal.name) //dog
    delete animal.name
    console.log(animal.name) //dog
    

    能够看到,configurable默许属性是true,设置为false以后,delete对象的属性将失效

须要注重的是,假如不是经由过程defineproperty定义的属性,形貌符默许值都是true;经由过程defineproperty定义的属性,形貌符默许是false

  • enumerable

    当且仅当该属性的enumerable为true时,该属性才够出现在对象的罗列属性中(for…in, Object.keys())。默以为 true。

    let animal = {
        name: 'cat'
     }
    for (let i in animal) {
        console.log(animal[i]) //cat
    }
    Object.defineProperty(animal, 'name', {
        enumerable: false
    })
    for (let i in animal) {
        console.log(animal[i]) //无输出
    }
    
    

数据形貌符其他属性:

  • value

    该属性对应的值。能够是任何有用的 JavaScript 值(数值,对象,函数等)。默以为 undefined。

  • writable

    当且仅当该属性的writable为true时,value才被赋值运算符转变。默以为 true。

存取形貌符其他属性:

  • get

    一个给属性供应 getter 的要领,假如没有 getter 则为 undefined。当接见该属性时,该要领会被实行,要领实行时没有参数传入,然则会传入this对象(因为继续关联,这里的this并不一定是定义该属性的对象)。

    
    let animal = {}
    let name = 'cat'
    Object.defineProperty(animal, 'name', {
      value: 'cat',
      get: function () {
        return name
      }
    })
    //报错:Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
    
    let animal = {}
    let name = 'cat'
    Object.defineProperty(animal, 'name', {
        get: function () {
          return name
        }
    })
    console.log(animal.name) //cat
    
    
    

假如一个形貌符不具有value,writable,get 和 set 恣意一个关键字,那末它将被以为是一个数据形貌符。假如一个形貌符同时有(value或writable)和(get或set)关键字,将会发生一个非常。

  • set

    一个给属性供应 setter 的要领,假如没有 setter 则为 undefined。当属性值修正时,触发实行该要领。该要领将接收唯一参数,即该属性新的参数值。

    
    let animal = {}
    let name = 'cat'
    Object.defineProperty(animal, 'name', {
        get: function () {
          return name
        },
        set: function (val) {
          name = val
        }
    })
    
    

假如接见者的属性是被继续的,它的 get 和set 要领会在子对象的属性被接见或许修正时被挪用。假如这些要领用一个变量存值,该值会被一切对象同享。

能够借助中心值来处理

    let animal = {}
    let name = 'cat'
    Object.defineProperty(animal, 'name', {
        get: function () {
          return this.stored_x
        },
        set: function (val) {
          this.stored_x = val
        }
    })

    

    原文作者:赵恩迟
    原文地址: https://segmentfault.com/a/1190000019036744
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞