Object.defineProperty() personal understanding

Object.defineProperty() personal understanding

Object.defineProperty() is used to define the properties of the properties in the object. These properties belong to the internal value of the object, so they cannot be accessed directly in JS.

In ES5, there are two attributes, includingData attributeswithAccessor properties

Data attributes

The data attribute contains aData valueThe position where you can read and write values, the data attribute has 4 characteristics used to describe its behavior

  • [[ Configurable ]] indicates whether you can delete the attribute, whether you can modify the characteristics of the attribute, whether you can change the attribute to an accessor attribute, when you define the attribute directly on the object, the default value is true
  • [[ Enumerable ]] Is it possible to return the attribute through a loop? Attribute defined directly on the object, this attribute defaults to true
  • [[ Writing ]] Is it possible to modify the value of the attribute. The attribute defined directly on the object, the default value of this attribute is true
  • [[ Value ]] The data value of the attribute. When reading an attribute value, read from this location, and when writing a new attribute, save the new value in this location. The default value is undefined

Use Object.defineProperty() to modify the default properties of the property, accepting three parameters: the object where the property is located, the property name, and a descriptor object. The property of the descriptor object must be the above four properties and cannot have other properties. Set one or more of the values, you can modify the corresponding characteristic value

Example:

let obj = {
    
    
    name: "lalala",
    age: 15,
    idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
    
    
    writable: false,    //不可被修改
    enumerable: false,   //不可被遍历
    value: "Well"  
})

console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //Well

Object.keys(obj).forEach(key => {
    
    
    console.log(key);   //age , idol   不包含name属性
})

The object.defineProperty() method can be called multiple times to modify the same property, but if the configurable is set to false for the first modification, it cannot be modified again, and an error will be reported

let obj = {
    
    
    name: "lalala",
    age: 15,
    idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
    
       //没有设置configurable:false是可以再次修改的
    writable: false,    //不可被修改
    enumerable: false,   //不可被遍历
    value: "Well"  
})

console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //Well

Object.keys(obj).forEach(key => {
    
    
    console.log(key);   //age , idol   不包含name属性
})



Object.defineProperty(obj , 'name' , {
    
    
    writable: true,    //该为true
    enumerable: false,   //不可被遍历
    value: "Well"  
})

obj.name = 'Nigo'   //可以修改属性了
console.log(obj.name)  //Nigo
let obj = {
    
    
    name: "lalala",
    age: 15,
    idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
    
       //没有设置configurable:false是可以再次修改的
    configurable:false,   //不可再次修改该属性的特性
    writable: false,    //不可被修改
    enumerable: false,   //不可被遍历
    value: "Well"  
})

console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //Well

Object.keys(obj).forEach(key => {
    
    
    console.log(key);   //age , idol   不包含name属性
})



Object.defineProperty(obj , 'name' , {
    
       //这里直接报错
    writable: true,    
    enumerable: false,   
    value: "Well"  
})


Accessor properties

The accessor property does not contain data values, but contains a pair of getter and setter functions (not required)

In addition, when a property has get and set methods, it is an accessor property

getter function

Function called when reading accessor properties

setter function

When writing accessor properties, call the setter function and pass in the new value, the setter function determines how to process the data

Accessor properties cannot be defined directly, they must also be defined by Object.defineProperty()

        const obj = {
    
    
            name: 'Well',
            _age: 22,  //表示只有通过对象方法能访问到的属性
        }

       Object.defineProperty(obj , 'age' , {
    
    
           configurable:true,   //表示能否delete删除属性,能否修改属性的特性,能否将属性改为数据属性,默认false
           enumerable: true,  //能否被遍历到,默认false
           get() {
    
    
               console.log("获取age的值");
               return this._age;
           },
           set(newV) {
    
    
               console.log("写入新值");
               this._age = newV;  //可以通过setter函数改变对象中的其他属性值
           }
       });
       obj.age = 24;  //写入新值
       console.log(obj.age); //获取age的值    24
       obj.age = 26;  //写入新值
       console.log(obj.age);  //获取age的值   26
       console.log(obj._age) //26

The attribute name of the accessor cannot be the same as the original attribute name of the object, otherwise the stack will overflow due to the endless loop

Changes in the data in the monitoring object:

 const obj = {
    
    
            a: 1,
            b: 2,
            c: 3
        }

        Object.keys(obj).forEach(key=>{
    
    
            let value = obj[key]
            Object.defineProperty(obj,key,{
    
    
                get(){
    
    
                    console.log(`获取${
      
      key}的行为被我劫持了`)
                    return value
                },
                set(v){
    
    
                    console.log(`${
      
      key}的改变被我劫持了`);
                    value = v;
                }
            })
        })
        console.log(obj.b);  //获取b的行为被我劫持了  2
        obj.c = 5;  //c的改变被我劫持了  

It is not necessary to define getter and setter at the same time

​ Only defining the setter means that it can only be written, not read. When reading a property without a getter, strict mode will report an error, and non-strict mode will return undefined

​ Only define the getter means you can only read, not write, try to write, an error will be reported in strict mode, and it will be ignored in non-strict mode

Define multiple attributes

Object.defineProperties(), this method receives two parameters, both of which are two objects, the first one is the object to add and modify properties

The attributes in the second object should correspond to the attributes added or modified in the first object

Example:

const people = {
    
    
    _name: 'Nigo',
    _age: 28
};

Object.defineProperties(people , {
    
    
    _name: {
    
    
        value: 'HaHa',
        //可修改其他特性
    }
    name: {
    
     //定义一个访问器属性
    	get() {
    
    
    		return this._name;
		}
	},
     age: {
    
    
         set(newV) {
    
    
             this._age = newV
         }
     }
})

Read the properties of attributes

Object.getOwnPropertyDescriptor()

The object where the attributes of the two parameters are located and the name of the attribute to be read, the return value of this method is an object

If it is a data attribute, the returned object contains configurable, enumerable, writabele, value

If it is an accessor attribute, the returned object contains configurable, enumerable, get, and set

In JS, you can use the Object.getOwnPropertyDescriptor() method on any object

Guess you like

Origin blog.csdn.net/YL971129/article/details/113733956