步步深入,理解vue的双向绑定一(Object.defineProperty)

Vue双向绑定原理学习笔记一(Object.defineProperty)

 相信大家使用vue的时候,一定不可避免地使用过vue的双向绑定,那么双向绑定的原理是啥?
 一直很好奇。但一直忙于项目,现在有了时间,终于可以一探究竟了。

和很多人一样,我刚开始不知道如何下手,就直接百度了一下双向绑定原理,看到最多的字眼就是 Object.defineProperty,由此可见,这个东西应该是双向绑定的核心之一,那么本片笔记就主要记载这个
Object.defineProperty

Object大家都知道,是js中最大的那个对象,那么从这个结构上我们可以知道,defineProperty一定是Object上定义的一个方法,好,继续查,查到了该函数的结构,是这样的 Object.defineProperty(obj, prop, descriptor),首先我们先搞清楚这个函数是干嘛的,看看官方的描述 “该方法允许精确地添加或修改对象的属性。”
???添加或修改对象的属性?搞这么麻烦干嘛,我们看看我们最简单粗暴的方法

let obj = {}
obj.name =‘zzz’
obj.age = ‘10’
console.log(obj.name) // zzz
console.log(obj.age ) // 10

这样不就行了嘛,那么为什么还要多走一圈用这个函数呢,等等,大家仔细读一下这个描述,精确添加或修改有意思了。有多精确呢?我们先看一看他的参数,obj 需要定义属性的当前对象prop 当前需要定义的属性名desc 属性描述符,前两个很好理解,不过这个desc是个啥? 查!
通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符,存取描述符,大开眼界,原来js的学问这么深,我们一个一个来看
首先数据描述符

let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
   writable: true // 是否可以改变
})

这个代码看起来还挺好理解,value就是Person对象中name属性的值,weitable就是是否能被改变,这就是数据描述符定义属性的方法,可以,继续!

存取描述符 --是由一对 getter、setter 函数功能来描述的属性
get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined。
set:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined。

作者:Weastsea链接:https://www.jianshu.com/p/8fe1382ba135

这样一解释,就不难看懂了,通过get获取,通过set设置!

let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
  get: function () {
    return temp
  },
  set: function (val) {
    temp = val
  }
})

两种设置方法都看完了,感觉并没有表达出 精确这两个字啊?我们再看看这些代码
在这里插入图片描述
configrable 描述属性是否配置,以及可否删除
enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中
writable:是否可以改变属性的值
这样一来就能看理解了,Object.defineProperty这个函数可以给对象的属性设置这些配置,至于有哪些具体的配置就不看了,对于理解双向绑定的帮助不大。这里主要介绍一下get和set
1,get和set是方法,因为是方法,所以可以进行判断
2,get是得到,一般是要返回的;set是设置,不用返回
3,如果调用对象内部的属性,约定的命名方式是_age( 即不采用临时变量的方法)
这个set和get久厉害了,它可以实现当对象属性发生变化时,我们可以利用setter得到一个反馈

举个栗子
在这里插入图片描述

再提一句:get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined

有了Object.defineProperty这个技术,我们可以实现一个简单的双向绑定效果了,代码如下

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="demo"></div>
    <input type="text" id="inp">
    <script>
        var obj  = {};
        var demo = document.querySelector('#demo')
        var inp = document.querySelector('#inp')
        Object.defineProperty(obj, 'name', {
            get: function() {
                return val;
            },
            set: function (newVal) {//当该属性被赋值的时候触发
                inp.value = newVal;
                demo.innerHTML = newVal;
            }
        })
        inp.addEventListener('input', function(e) {
            // 给obj的name属性赋值,进而触发该属性的set方法
            obj.name = e.target.value;
        });
        obj.name = 'fei';//在给obj设置name属性的时候,触发了set这个方法
    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值