美文网首页Vuejs让前端飞
实现 MVVM (一)- Object.definePrope

实现 MVVM (一)- Object.definePrope

作者: passMaker | 来源:发表于2018-10-10 16:55 被阅读12次

    动机 (写在前面)

    之前在学习构建自己轮子组件库时,被反复的提到了 MVVM 核心实现方法的问题,其中包括 Vuejs 的原理。逛过一些技术社区。一些前辈和大佬给出了建议。初级水平的人并不推荐去看 Vuejs 的源码,截止到今天,Vuejs 2.5.17 版本的源码高达 10978 行。因此初级水平的人看源码性价比也许真的并不高。一些前辈和大牛给出的建议是,Vuejs 的实现原理尤雨溪已经说得很明白了。建议大家可以使用自己的方式去简单模拟一下 MVVM 的思想,也许可能实现得并不优雅。但这样做比头铁的看源码来得更有价值和意义。

    本文是我通过已经知晓的 Vuejs 实现原理来简单实现 MVVM 的系列博文的第一篇,主要总结归纳了 Object.defineProperty() 的方法特性。

    Object.defineProperty

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。其语法是:

    Object.defineProperty(obj, prop, descriptor)
    

    参数说明(三个参数都是必须的):

    obj   // 要在其上定义属性的对象。
    prop   // 要定义或修改的属性的名称。
    descriptor   // 将被定义或修改的属性描述符。
    

    返回值为传入参数的对象,即第一个参数 obj

    使用方法

    以下三种方法都可以用来定义/修改一个对象属性,其中包含 Object.defineProperty() 方法。

    var obj = {}
    obj.name = 'evenyao'
    obj['age'] = 27
    Object.defineProperty(obj, 'intro', {
        value : 'hello world'
    })
    
    console.log(obj)  // {name: 'evenyao', age: 27, intro: 'hello world'}
    

    configurable

    configurable 是该方法传参中最后一项 descriptor 中的属性描述符。configurable 的值设置为 false 后(如果没设置,默认就是 false)。以后就不能再次通过 Object.defineProperty() 方法修改属性,也无法删除该属性。如果configurable 的值设置为 true 后,能删除该属性,但也不能修改。

    举例说明:

    var obj = {}
    Object.defineProperty(obj, 'intro', {
        configurable: false,
        value : 'hello world'
    })
    obj.intro = 'i wanna change it'
    console.log(obj.intro)   // "hello world"
    delete obj.intro           // false, 删除失败
    console.log(obj.intro)  // "hello world" 
    
    Object.defineProperty(obj, 'name', {
        configurable: true,
        value : 'i wanna change it'
    })
    delete obj.intro   // true  , 成功删除
    

    enumerable

    enumerable 也是该方法传参中最后一项 descriptor 中的属性描述符。设置 enumerable 属性为false 后,遍历对象的时候会忽略当前属性(如果未设置,默认就是 false 不可遍历)。

    举例说明:

    var obj = {name: 'evenyao'}
    Object.defineProperty(obj, 'age', {
        enumerable: false,
        value: 27
    })
    
    for(var key in obj){
        console.log(key)   // 只输出 'name', 不输出'age'
    }
    

    value 和 writable

    valuewritable数据描述符,具有以下可选键值:

    • value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
    • writable: 当且仅当该属性的 writabletrue 时,该属性才能被赋值运算符改变。但不能删除。该属性默认为 false

    举例说明:

    var obj = {name: 'evenyao'}
    Object.defineProperty(obj, 'age', {
        value: 27,
        writable: false
    })
    
    obj.age = 26
    console.log(obj.age)   // 27, writable为 false 时,修改对象的当前属性值无效
    

    区别

    configurable: truewriable: true 的区别是,前者是设置属性能删除,后者是设置属性能修改

    get 和 set

    getset存取描述符,有以下可选键值:

    • get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined
    • set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined
    var obj = {}
    var age 
    Object.defineProperty(obj, 'age', {
        get: function(){
            console.log('get age...')
            return age
        },
        set: function(val){
            console.log('set age...')
            age = val
        }
    })
    
    obj.age = 100  // 'set age...'
    console.log(obj.age) // 'get age...', 100
    



    值得一提的是这个案例和之前我在 从「闭包」到 思考人生 那篇文章里面封装的那个闭包函数(中文的案例2)是很相似的。事实上在我看来,他们所达到的效果是一样的。

    var Age = (function(){
      var age = undefined
      function set(s){
        age = s
        console.log('set age...')
      }
      function get(){
        console.log('get age...')
        return age 
      }
      return {
        set: set,
        get: get
      }
    })()
    
    Age.set(100)  // 'set age...'
    Age.get()  // 100
    



    数据描述符存取描述符 是不能同时存在的。如果同时存在,代码就会报错。

    例如下面例子,就是不被允许的。这段代码同时出现了 valueget/ set。所以会报错。

    var obj = {}
    var age 
    Object.defineProperty(obj, 'age', {
        value: 27,
        get: function(){
            console.log('get age...')
            return age
        },
        set: function(val){
            console.log('set age...')
            age = val
        }
    })
    

    相关文章

      网友评论

        本文标题:实现 MVVM (一)- Object.definePrope

        本文链接:https://www.haomeiwen.com/subject/ieopaftx.html