从Vue源码学习JavaScript之Object.defineproperty

栏目: 编程语言 · 发布时间: 6年前

内容简介:学Vue最耳熟能详的词就是Object.defineproperty,这篇文章就介绍一下这个属性。Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。Object.defineProperty(obj, prop, descriptor)

学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
        }
    })

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

机器与人:埃森哲论新人工智能

机器与人:埃森哲论新人工智能

【美】保罗•多尔蒂 詹姆斯•威尔逊 / 赵亚男 / 中信出版社 / 2018-10-1 / 49.00元

自人工智能问世以来,人们普遍持有人机对立的观点,且无时无刻不在害怕自己的工作会被人工智能取代。作者认为,是时候抛开这些无谓的担忧了,因为人类社会正走向一个与机器共融共生的时代。 未来的新型工作模式是什么?未来有哪些工作不会被人工智能取代?人工智能时代重要的生存技能是什么?本书围绕这三大核心问题做了透彻的分析。作者带我们见识了置于业务流程背景之下的人工智能,阐述了其在不同职能部门中起到的推动作......一起来看看 《机器与人:埃森哲论新人工智能》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具