js中对象Object的defineProperty等基础理解

2019-10-11  本文已影响0人  jadefan

面向对象的语言都有类的概念,通过类可以创建多个对象
js中没有类,但通过Object可以实现类似功能

Object定义

创建Object最简单的方法是(构造函数):

    var obj = new Object();
    obj.name = 'person'

或(对象字面量)

    var obj = {
      name: 'person'
    }

对象的创建方式还有很多,比如工厂模式、构造函数模式、原型模式、构造函数与原型组合模式、动态原型模式、寄生构造函数模式、稳妥构造函数模式等,后续详细介绍。

Object属性

Object的属性有两种类型:数据属性和访问器属性

数据属性包含一个数据值的位置,在这个位置可以读取和写入。另有4个描述其行为的特征
访问器属性不包含数据值,包含一对getter和setter函数,另有4个描述其行为的的特征

看个例子:

    var person = {} 
    
    Object.defineProperty(person, '_name', {
      configurable: false,
      enumerable: false,
      writable: true,
      value: 'wang',
    }) 

    Object.defineProperty(person, 'name', {
      configurable: false,
      enumerable: false,
      get: function () {
        return 'get ' + this._name;
      },
      set: function (name) {
        this._name = 'new ' + name
      },
    })

    console.log(person._name);  //wang
    console.log(person.name);   //get wang
    person.name = 'liu'
    console.log(person._name);  //new liu
    console.log(person.name);   //get new liu

上述代码中_name即为数据属性,name为访问器属性,
能看出数据属性的特征值:

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认true
[[Enumerable]]:表示能否通过for-in循环返回属性,默认为true
[[Writable]]:表示能否修改属性的值,默认为true
[[Value]]:属性的数据值,默认为undefined

访问器属性的特征值:

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认true
[[Enumerable]]:表示能否通过for-in循环返回属性,默认为true
[[Get]]:在读取属性时调用的函数,默认值为undefined
[[Set]]:在写入属性时调用的函数,默认值为undefined

此处的默认值指通过构造函数或字面量定义属性时的默认值,如果通过defineProperty定义属性,而没有指定特征值,则都默认为false

定义多个属性

在需要定义多个属性时,可以用到defineProperties

    Object.defineProperties(person,{
      _name:{ 
        value:'wang',
      },
      name:{
        get:function(){
          return 'get ' + this._name;
        },
        set:function(name){
          this._name = 'new ' + name
        }
      }
    })

读取属性的特征

通过Object.getOwnPropertyDescriptor可以读取到对象属性的特征
用这个来验证下默认值

    var person = {}
    person.age = 18;
    Object.defineProperty(person, 'name', { 
      value: 'wang',
    }) 
    console.log(Object.getOwnPropertyDescriptor(person, 'age'))
    //{value: 18, writable: true, enumerable: true, configurable: true}
    console.log(Object.getOwnPropertyDescriptor(person, 'name'))
    //{value: "wang", writable: false, enumerable: false, configurable: false}

引申用途

defineProperty的经典使用案例便是Vue.js的双向绑定机制
也就是通过object访问器属性的setter函数中获取到属性数据的更新,从而通知所有订阅者以做出响应
详细解析后续分析

上一篇 下一篇

猜你喜欢

热点阅读