美文网首页
MVVM(1):理解Object.definePropety

MVVM(1):理解Object.definePropety

作者: 晓露_0d5c | 来源:发表于2020-11-27 23:43 被阅读0次

    Object.defineProperty()方法

    1、mdn地址

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

    2、Object.definePropery默认:

    • configurable:false //当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。

    • enumerable:false

    • value:undefined //很好理解,只声明不赋值,值就是undefined

    • writable:false //当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。 默认为 false。

    • get:undefined // 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
      默认为 undefined。

    • set:undefined // 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
      默认为 undefined。

    3、对象属性的可枚举性 enumerable

    • for..in循环 :只遍历对象自身的和继承的可枚举的属性

    • Object.keys方法 :返回对象自身的所有可枚举的属性的键名

    • JSON.stringify方法:只串行化对象自身的可枚举的属性

    • Object.assign()(ES6)

    1、for...in 和 Object.keys

    • for...in会返回继承的属性。
    • for...in循环和Object.keys方法的区别:
      (1)前者包括对象继承自原型对象的属性,
      (2)后者只包括对象本身的属性。如果需要获取对象自身的所有属性,不管enumerable的值,可以使用
      let Parent = function () {
          this.name = '888',
            this.say = function () {
              console.log('say---')
            }
        }
    
        let Children = function () { }
        Children.prototype = new Parent()
    
        let p = new Parent()
        let c = new Children()
    
        p.say()
        c.say()
    
        for (let item in p) {
          console.log("item", item)
          // 打印结果
          // 第一次:item name
          // 第二次:item say
        }
        for (let cItem in c) {
          console.log("cItem", cItem)
          // 打印结果
          // 第一次:item name
          // 第二次:item say
        }
    
        console.log("p keys", Object.keys(p))
        // 打印结果
        // p keys   ["name","key"]
    
    
        console.log("c keys", Object.keys(c))
        // 打印结果
        // c keys   []
    

    2、JSON.stringify

    • 只串行化对象自身的可枚举的属性,继承来的属性并不会被转化成字符串
    • 再次使用JSON.parse 拿到的对象会发现,新对象并没有元对象继承的属性和方法
        let Father = function () {
          this.lastName = 'zhang'
          this.country = 'China'
        }
        let Children = function () {
        }
    
        Children.prototype = new Father()
    
        let f = new Father()
        let c = new Children()
    
        console.log(f)
        /*
        * country: "China" 
        * lastName: "zhang" 
        * __proto__: Object
        */
    
        console.log(c)
        /*
        * __proto__: Father
        */
    
        console.log(JSON.stringify(f)) //{"lastName":"zhang","country":"China"}
        console.log(JSON.stringify(c)) //{}
    
        let f2 = JSON.parse(JSON.stringify(f))
        let c2 = JSON.parse(JSON.stringify(c))
    
        console.log("f2 lastName:", f2.lastName) //zhang
        console.log("c2 lastName:", c2.lastName) // undefined
    

    3、Object.assign()

    • 没什么神奇的,得到的新对象和原来的对象继承一样的属性和方法,原型是一样的,由此可以看出为啥vue中要使用这个方法更改对象了
    let a = Object.assign({}, { a: 3 })
        console.log("a:", a)
    
    
        let Father = function () {
          this.lastName = "liu"
          this.country = "China"
        }
        let Children = function () { }
    
        Children.prototype = new Father()
    
        let f = new Father()
        let c = new Children()
    
    
        console.log("f", JSON.stringify(f))
        console.log("c", JSON.stringify(c))
    
        let f1 = JSON.parse(JSON.stringify(f))
        let c1 = JSON.parse(JSON.stringify(c))
        console.log("f1", f1.lastName) // liu
        console.log("c1", c1.lastName) // undefined
    
        let r1 = Object.assign(f, { dd: 34 })
        console.log("r1:", r1)
        console.log(r1.lastName) //liu
    
        let r2 = Object.assign(c, { dd: 33 })
        console.log("r2:", r2)
        console.log(r2.lastName) // liu
    

    4、writable默认是false

        let obj = { a: 333 }
        console.log("obj:", obj.a) //333
    
        obj.a = 444
        console.log("obj", obj.a) //444
    
    
    
        let obj2 = {}
        Object.defineProperty(obj2, 'a', {
          value: 333
        })
        console.log("obj2:", obj2.a) //333
    
        obj2.a = 444
        console.log("obj2:", obj2.a) //333
    
        // 由此可以看出 Object.defineProperty默认的writable是false
    

    5、get和set

    • 有get和set,不能写 value、writable描述符
    <!-- get和set方法理解 -->
        let obj = {}
        Object.defineProperty(obj, 'a', {
          set(val) {
            console.log("set a")
          },
          get() {
            return 333
          }
        })
    
        console.log(obj.a) //333
    
        obj.a = 444 //  set a
    
        console.log(obj.a) //333
    
    let obj = {}
        Object.defineProperty(obj, 'a', {
          // value: 333, // 有get和set,写value描述符会报错
          // writable: true, // 有get和set,写writable描述符会报错
          configurable: true,
          enumerable: true,
          get() {
            return this.value
          },
          set(val) {
            this.value = val
          }
        })
    
        console.log(obj.a) // undefined
    
        obj.a = 333
    
        console.log(obj.a) // 333
    

    相关文章

      网友评论

          本文标题:MVVM(1):理解Object.definePropety

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