• 理解Object.defineProperty()


    理解Object.defineProperty()

    Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

    基本语法:Object.defineProperty(obj, prop, descriptor)
    @param obj 【必须】目标对象
    @param prop【必须】新增或修改的属性名字
    @param descriptor 属性描述符。
    属性描述符 包括两种形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对getter-setter函数功能来描述的属性。
    但是该两者不能同时存在,描述符只能是其中之一。

    一:数据描述符:
    比如如下一个普通对象:

    var obj = {
      "name": "kongzhi"
    };

    数据描述符属性如下:

    Object.defineProperty(obj, "name", {
      configurable: true | false,
      enumerable: true | false,
      value: '任意类型的值',
      writable: true | false
    });

    下面我们来理解下每个属性的含义:

    1. value:
    含义: 属性的值,可以是任何类型的值,默认为undefined

    1-1 不设置value属性
    如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {});
    console.log(obj.name); // undefined

    1-2 设置value属性

    // 设置value 代码如下:
    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi"
    });
    console.log(obj.name); // kongzhi

    2. writable

    含义:属性的值是否可以被重写,true: 可以被重写,false: 不能被重写。默认为false。

    2-1 writable设置为false,不能重写,如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: false
    });
    // 先打印下值
    console.log(obj.name); // kongzhi
    // 更改值 
    obj.name = "longen";
    // 再打印下 
    console.log(obj.name); // kongzhi

    2-2 writable设置为true,可以被重写,如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: true
    });
    // 先打印下值
    console.log(obj.name); // kongzhi
    // 更改值 
    obj.name = "longen";
    // 再打印下 
    console.log(obj.name); // longen

    3. enumerable

    含义:该属性是否可以被枚举(如:for..in 或 Object.keys()). 如果为true的话,可以被枚举,设置为false的话,不能被枚举,默认为false。

    3-1 enumerable被设置为false,不能被枚举,如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: false,
      enumerable: false
    });
    // 先打印对象一下看看
    console.log(obj); // {name: "kongzhi"}
    
    // 再枚举对象的属性
    for(var attr in obj) {
      console.log(attr); // 什么都没有输出 说明不能被枚举
    }

    3-2 enumerable 设置为true,可以被枚举,如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: false,
      enumerable: true
    });
    // 先打印对象一下看看
    console.log(obj); // {name: "kongzhi"}
    
    // 再枚举对象的属性
    for(var attr in obj) {
      console.log(attr); // 输出 name
    }

    4. configurable

    含义:是否可以删除目标属性或是否可以修改目标属性的特性。如果为true的话,可以被删除或可以修改属性,为false的话,不能删除目标属性或不能修改目标属性,默认为false

    4-1 configurable: false, 为false的话,不能删除目标属性或不能修改目标属性。如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: false,
      enumerable: false,
      configurable: false
    });
    // 先打印对象一下看看
    console.log(obj); // {name: "kongzhi"}
    
    // 删除属性 
    delete obj.name;
    // 重新打印下对象,看是否删除成功了
    console.log(obj.name); // kongzhi
    
    // 修改属性 
    obj.name = "longen";
    // 重新打印下对象,看是否修改成功了
    console.log(obj.name); // kongzhi 

    4-2 configurable: true, 可以删除目标属性 或 可以修改目标属性,如下代码:

    var obj = {};
    Object.defineProperty(obj, "name", {
      value: "kongzhi",
      writable: false,
      enumerable: false,
      configurable: true
    });
    // 先打印对象一下看看
    console.log(obj); // {name: "kongzhi"}
    
    // 删除属性 
    delete obj.name;
    // 重新打印下对象,看是否删除成功了
    console.log(obj.name); // undefined
    
    // 修改属性 
    obj.name = "longen";
    // 重新打印下对象,看是否修改成功了
    console.log(obj.name); // longen 

    二: 存取器描述
    使用存取器描述属性的时候,可以使用如下属性:

    var obj = {};
    Object.defineProperty(obj, "name", {
      enumerable: true | false,
      configurable: true | false,
      get: function() {} | undefined,
      set: function(value) {} | undefined
    });

    注意:当使用了getter或setter的时候,就不能使用writable和value这两个属性。否则会报错。

    getter 是获取属性值的方法。如果没有getter 则默认为 undefined,当我们读取某个属性的时候,其实是在对象内部调用了该方法,该方法必须使用return语句,返回值被作为属性值。
    setter 是设置属性的方法。如果没有setter,则默认为undefined,该方法接收一个参数,并将该参数值分配该属性。当我们设置某个属性的时候,实际上在对象的内部调用了该方法。

    如下代码是使用getter和setter的代码:

    var obj = {};
    var initValue = "kongzhi";
    Object.defineProperty(obj, "name", {
      get: function() {
        // 当获取属性值的时候触发的函数
        return initValue;
      } ,
      set: function(value) {
        // 当设置值的时候触发的函数
        initValue = value;
      } 
    });
    // 获取值
    console.log(obj.name); // kongzhi
    
    // 设置值
    obj.name = "longen";
    // 打印下
    console.log(obj.name); // longen
  • 相关阅读:
    053-146
    053-659
    053-658
    053-657
    053-656
    053-654
    053-655
    053-652
    053-651
    053-650
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/7465494.html
Copyright © 2020-2023  润新知