理解Object.defineProperty的作用

defineProperty的属性

Object.defineProperty定义新属性或修改原有的属性 

Object.defineProperty(obj, prop, descriptor)

参数说明:

obj:必需。目标对象 
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性

descriptor里面的属性都是可选的,每一个属性的作用如下,具体的使用方法详见官方文档,这里只是大致罗列出来个属性

  1. value 该属性对应的值,可以是任意类型的值,默认为undefined
  2. writeable 该属性的值是否可以被重写 默认是false不能被重写
  3. enumberable 该属性是否可以被枚举(使用for...in 或者Object.keys()能遍历出来)默认是false 不可被枚举
  4. configurable 是否可以删除目标属性或是否可以再次修改属性的特性(writable, configurable, enumerable)。设置为true可以被删除或可以重新设置特性;设置为false,不能被可以被删除或不可以重新设置特性。默认为false。

    这个属性起到两个作用:目标属性是否可以使用delete删除 目标属性是否可以再次设置特性

第5个属性就是存取器(注意:当使用了getter或setter方法,不允许使用writable和value这两个属性)

 相信用过vue的同学,对vue的数据双向绑定的原理有一定的了解,那就是数据劫持,就是用的Object.defineProperty这个方法,里面定义了setter和getter方法,通过观察者模式(发布订阅模式)来监听数据的变化,从而做相应的逻辑处理。

  let obj = {}
  let initVal = 123
  Object.defineProperty(obj, 'age', {
    set: function(val) {
      console.log("改变")
      initVal = val
    },
    get: function() {
      return initVal
    }
  })
  console.log(obj.age) // 执行get 方法 输出123
  obj.age = 456 // 执行set 方法 输出改变 这时的initVal 赋值为456
  console.log(obj.age) // 输出456

这里就具体讲解vue数据双向绑定的原理了,这里分享一个通过defineProperty解决异步状态判断的问题。在实际项目中H5与原生APP的交互还是很多,这里我们定下的协议就是 调用原生的方法的时候,必须先调用ready初始化方法,只有调用ready成功后,才能调用后续的方法,后续的方法这里用getUserInfo方法作为例子

// 正常采用promise的处理
  
  function Ready(){
    retrun new Promise((resolve,reject)=>{
        // 原生的ready 方法
        function ready(){
            resolve()
        }
        ready()
    })
  }
  Ready().then(()=>{
    getUserInfo()
  })

但是实际情况的话,加上jsBridge,会显得很复杂,实现起来也不是很简单 考虑的就是定义一个全局变量stats 设置为false,在ready放法中改变state的值,触发set 方法 通过判断来执行 resolve,

  let _resolve = null; // 用来将promise的resovle 保存 延迟将Promise对象的状态从“未完成”变为“成功”
  let promise = new Promise(resolve => {_resolve=resolve})
  let obj = {}
  let _state = false
  Object.defineProperty(obj, 'state', {
    set: function(val) {
      !state && val && _resolve ()
      _state = val
    },
    get: function() {
      return _state 
    }
  })
  // 这里的then方法不会立马被调用 因为没有执行resovle 
  promise.then(()=>{
    getUserInfo()
  })
  // 模拟异步调用 原生的方法
  setTimeOut(()=>{
      obj.state = true 
  },1000)

这只是一个简答的例子,实际运用的时候会有点出入,掌握这个思想最为重要,其次对promise的理解要深刻。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值