zoukankan      html  css  js  c++  java
  • Object.defineProperty()方法学习笔记

    这是js中一个非常重要的方法,ES6中某些方法的实现依赖于它,VUE通过它实现双向绑定

    此方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象

    参数

    Object.defineProperty(object, attribute, descriptor)

    这三个参数都是必输项

    第一个参数为目标对象

    第二个参数为需要定义的属性或者方法

    第三个参数为目标属性所拥有的特性

    前两个参数都很明确,重点是第三个参数 descriptor, 它有以下取值

    descriptor

    value: 属性的值

    writable: 属性的值是否可被重写(默认为false)

    configurable: 总开关,是否可配置,若为false, 则其他都为false(默认为false)

    enumerable: 属性是否可被枚举(默认为false)

    get: 获取该属性的值时调用

    set: 重写该属性的值时调用

    一个例子 

    var a= {}
    Object.defineProperty(a,"b",{
       value:123
    })
    console.log(a.b)  //123
    a.b = 456
    console.log(a.b)  //123
    a.c = 110
    for (item in a) {
        console.log(item, a[item])    //c 110
    }

    因为 writable 和 enumerable 默认值为 false, 所以对 a.b 赋值无效,也无法遍历它

    configurable

    总开关,是否可配置,设置为 false 后,就不能再设置了,否则报错, 例子

    var a= {}
    Object.defineProperty(a,"b",{
      configurable:false
    })
    Object.defineProperty(a,"b",{
      configurable:true
    })
    //error: Uncaught TypeError: Cannot redefine property: b

    writable

    是否可重写

    var a = {}; 
    Object.defineProperty(a, "b", { 
        value : 123,
        writable : false 
    });
    console.log(a.b);
    // 打印 123 a.b = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值) console.log(a.b); // 打印 123, 赋值不起作用。

    enumerable

    属性特性 enumerable 定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举

    var a= {}
    Object.defineProperty(a,"b",{
      value:3445,
      enumerable:true
    })
    console.log(Object.keys(a));// 打印["b"]

    enumerable改为false

    var a= {}
    Object.defineProperty(a,"b",{
      value:3445,
      enumerable:false //注意咯这里改了
    })
    console.log(Object.keys(a));// 打印[]

    set 和 get

    如果设置了 set 或 get, 就不能设置 writable 和 value 中的任何一个,否则报错

    var a = {}
    Object.defineProperty(a, 'abc', {
        value: 123,
        get: function() {
            return value
        }
    })
    //Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object> at Function.defineProperty 

    对目标对象的目标属性 赋值和取值 时, 分别触发 set 和 get 方法

    var a = {}
    var b = 1
    Object.defineProperty(a,"b",{
      set:function(newValue){
          b = 99;
        console.log("你要赋值给我,我的新值是"+newValue);
      },
      get:function(){
        console.log("你取我的值");
        return 2 //注意这里,我硬编码返回2
      }
    })
    a.b = 1 //打印 你要赋值给我,我的新值是1
    console.log(b)        //打印 99
    console.log(a.b)    //打印 你取我的值
                        //打印 2    注意这里,和我的硬编码相同的

    上面的代码中,给a.b赋值,b的值也跟着改变了。原因是给a.b赋值,自动调用了set方法,在set方法中改变了b的值。vue双向绑定的原理就是这个。

    扩展

    Reflect.defineProperty()

     可以使用ES6的静态方法 Reflect.defineProperty(), 使用起来和 Object.defineProperty 完全一样,唯一的不同是修改属性的配置出错时,返回false, 不抛错。  例子:

    var a = {}
    Reflect.defineProperty(a, "b", {
        value: 2,
        configurable: false
    })
    Reflect.defineProperty(a, "b", {
        value: 2,
        configurable: true
    })
    //  返回false
    var a = {}
    Reflect.defineProperty(a, "b", {
        value: 2,
        configurable: false
    })
    Object.defineProperty(a, "b", {
        value: 2,
        configurable: true
    })
    //Uncaught TypeError: Cannot redefine property: b at Function.defineProperty (<anonymous>)  at <anonymous>:6:8

    Object.defineProperties

    此方法可以一次设置多个属性,例子:

    var a = {}
    Object.defineProperties(a, {
        c: {
            value: 1
        },
        d: {
            value: 2
        }
    })
    // 返回{c: 1, d: 2}

    用Object.defineProperty实现黑科技

    使 a==1 && a==2 && a==3 为true

    var b = 1
    Object.defineProperty(window, "a", {
        get: function() {
            return b++
        }
    })
    console.log(a==1 && a==2 && a==3) //返回true

    除此之外,还可以用对象的 toString() 方法来实现

    var a = {
        b: 1,
        toString() {
            return this.b++
        }
    }
    console.log(a==1 && a==2 && a==3)  //返回true

    ps: 这是本人在博客园写的第一个博客,欢迎大家多对支持和提出意见建议

    参考:https://www.cnblogs.com/weiqu/p/5860945.html

  • 相关阅读:
    实时27实战机器学习:图片验证码识别(Java实现)
    大屏26深度学习模型来从文档图片中自动化地提取出关键信息成为一项亟待解决的挑战
    f-string想必作为Python3.6版本开始引入的特性,通过它我们可以更加方便地向字符串中嵌入自定义内容
    大屏25JAVA+selenium+tess4j识别登陆验证码截图与识别
    前端12 highcharts和echarts选择
    大屏20基于 Selenium 的 Web 自动化测试框架完美版自动化解决方案 [开源项目]
    大屏24字典python+selenium的行为
    大屏23Tesseract字库训练Tesseract 3
    大屏21解决数据问题python-tesseract-ocr的安装及使用
    大屏22解决数据问题java浏览器源.docx
  • 原文地址:https://www.cnblogs.com/zhaowj/p/9576450.html
Copyright © 2011-2022 走看看