★ Object.defineProperty () and defineProperties () JavaScript in

Object of defineProperty defineProperties and importance of these two methods is important in the js, the main function is used to define or modify these internal attributes, and corresponding thereto getOwnPropertyDescriptor getOwnPropertyDescriptors line is acquired, this internal property.

The following describes the meaning of Article My first attribute data representative of the access descriptor and the descriptor, and then briefly above four basic functions of the method, which can skip to know if, and finally I will illustrate expansion properties described in the respective internal the actual effect produced under the kinds of scenes, that is the core content of this article. This article describes about the conceptual or will make use of "javaScript Advanced Course", the concept of MDN websites, ensure accurate and easy to understand, explain part of the combination of personal understanding and illustration.


Data (data descriptor) properties

There are four data attributes describe internal properties characteristic

[[Configurable]]

By indicating whether delete remove this property, can modify the characteristics of the attribute, or modify the attribute can modify the access attributes, if the literal definition of the object directly, a default value is true.

[[Enumerable]]

Indicates whether the attribute can be enumerated, i.e., whether to return the attributes for-in loop or Object.keys (), if direct literal definition object, the default is true

[[Writable]]

Can modify the value of the property, if direct literal definition object, the default is true

[[Value]]

Corresponding to the attribute value default is undefined


Accessor (Access Descriptor) properties

Access properties described also has four internal property characteristics

[[Configurable]]

And [[the Configurable]] as the attribute data, attributes indicating whether to delete the delete, can modify the properties of the properties, or the ability to modify the access attribute modification properties, if the literal definition of the object directly, the default value true

[[Enumerable]]

And [[the Configurable]] as the attribute data indicating whether the attribute can be enumerated, i.e., whether to return the attributes for-in loop or Object.keys (), if direct literal definition object, the default is true

[[GET]]

To provide a property getter method (function call to access the object property, the return value is the current value of the property), if there is no getter was undefined. The return value is used as the method attribute value. The default is undefined

[[SET]]

To provide a property setter method (function called when the object is set to the value of property), if no setter was undefined. This method takes a unique parameter, and the new value of the parameter assigned to the attribute. The default is undefined


Create / modify / get property method


YI、Object.defineProperty()

Function:
The method defines an object directly on a new attribute, or modify existing properties of an object and return the object. If no configurable, writable, enumerable, these properties default is false, if not specified value, get, set, the default value of these attributes undefined
语法: Object.defineProperty(obj, prop, descriptor)
obj: a target object to be operated
prop: a target object needs to be defined or modified name of the attribute
descriptor: attributes will be defined or modified descriptor

 var obj = new Object();
 
 Object.defineProperty(obj, 'name', {
     configurable: false,
     writable: true,
     enumerable: true,
     value: '张三'
 })
 
 console.log(obj.name)  //张三
ER、Object.defineProperties()

Function:
The method of directly defining one or more new attributes on an object or modify an existing attribute, and returns the object.
语法:Object.defineProperties(obj,props)
obj: to be added or modified attributes of the object.
props: one or more key of the object to be configured to add or modify specific properties of the object defined for

 var obj = new Object();
 Object.defineProperties(obj, {
     name: {
         value: '张三',
         configurable: false,
         writable: true,
         enumerable: true
     },
     age: {
         value: 18,
         configurable: true
     }
 })
 
 console.log(obj.name, obj.age) // 张三, 18
SAN、Object.getOwnPropertyDescriptor()

Function:
This attribute describes a method returns its own property on the specified object corresponding (own attribute refers to the attribute of the object directly applied, need not be from the property to find the prototype chain)
语法: Object.getOwnPropertyDescriptor(obj, prop)// obj: a need to find a target objects, prop: the name of the target object property

 var person = {
     name: '张三',
     age: 18
 }
 
 var desc = Object.getOwnPropertyDescriptor(person, 'name'); 
 console.log(desc)  结果如下
 // {
 //     configurable: true,
 //     enumerable: true,
 //     writable: true,
 //     value: "张三"
 // }

SI、Object. getOwnPropertyDescriptors()

Function: The all own attribute descriptor specified object, if there is no attribute itself, returns the empty object.
语法: Object.getOwnPropertyDescriptors(obj)// obj: a need to find the target object

 var person = {
     name: '张三',
     age: 18
 }
 var desc = Object.getOwnPropertyDescriptors(person);
 console.log(desc) 
 //   age: {
 //   value: 18, writable: true, enumerable: true, configurable: true}
 //    name: {
 //   value: "张三", writable: true, enumerable: true, configurable: true}
 //    __proto__: Object

Examples of various expansion properties of the scene descriptor explain

.configurable

If configurable property is false, then the operator can not use the delete (throw errors in strict mode),修改所有内部属性值会抛出错误

Add a descriptor attribute data in the object
 var person = {};
 
 Object.defineProperty(person, 'name', {
     configurable: false,
     value: 'John'
 }) ;
 
 delete person.name   // 严格模式下抛出错误
 
 console.log(person.name)  // 'John'  没有删除
 
 Object.defineProperty(person, 'name', {
     configurable: true  //报错
 });
 
 Object.defineProperty(person, 'name', {
     enumerable: 2  //报错
 });
 
 Object.defineProperty(person, 'name', {
     writable: true  //报错
 });
 
 Object.defineProperty(person, 'name', {
     value: 2  //报错
 });

Note: The above is initially-defined attribute descriptor ·, writabl default is false, the above effect will only appear if the writable defined as true, you can be modified [[writable]] and [[value]] property values, additional modifications given two property values:

 var obj = {};
 
 Object.defineProperty(obj, 'a', {
     configurable: false,
     writable: true,
     value: 1
 });
 
 Object.defineProperty(obj, 'a', {
     // configurable: true, //报错
     // enumerable: true,  //报错
     writable: false,
     value: 2
 });
 var d = Object.getOwnPropertyDescriptor(obj, 'a')
 console.log(d);
 // {
 //     value: 2, 
 //     writable: false, 
 // }
Add access in an object descriptor attribute
 var obj = {};
 var aValue; //如果不初始化变量, 不给下面的a属性设置值,直接读取会报错aValue is not defined
 var b;
 Object.defineProperty(obj, 'a', {
     configurable : true,
     enumerable : true,
    get: function() {
         return aValue
     },
    set: function(newValue) {
         aValue = newValue;
         b = newValue + 1
     }
 })
 console.log(b) // undefined
 console.log(obj.a)  // undefined, 当读取属性值时,调用get方法,返回undefined
 obj.a = 2;  // 当设置属性值时,调用set方法,aValue为2
 
 console.log(obj.a) // 2  读取属性值,调用get方法,此时aValue为2
 console.log(b) // 3  再给obj.a赋值时,执行set方法,b的值被修改为2,额外说一句,vue中的计算属性就是利用setter来实现的

note:

  • getter and setter can not be used simultaneously, but only one in use strict mode, it will throw an error.
  • And access data descriptor descriptor can not be mixed, otherwise it will throw an error.
  • Any variables var defined, which configurableattribute values are false, the same object is also defined.
Writable

When Writable to false (and configurable as true), [value] can defineProperty modified, but not modified directly assigned.

 var obj = {};

Object.defineProperty(obj, 'a', {
    configurable: true,
    enumerable: false,
     writable: false,
    value: 1
});

Object.defineProperty(obj, 'a', {
    configurable: false,
    enumerable: true,
    writable: false ,
    value: 2
});
var d = Object.getOwnPropertyDescriptor(obj, 'a')

console.log(d); // 结果如下
// {
//     value: 2, 
//     writable: false, 
//     enumerable: true, 
//     configurable: false
// }


但是如果直接复制修改
var obj = {}

Object.defineProperty(obj, 'a', {
    configurable: true,
    enumerable: false,
    writable: false,
    value: 1
});
obj.a=2;
var d = Object.getOwnPropertyDescriptor(obj, 'a')

console.log(d); // 结果如下

// {
//     value: 1,  // 没有做出修改
//     writable: false, 
//     enumerable: true, 
//     configurable: false
// }
Enumerable

Directly on examples

 var obj = {};
Object.defineProperties(obj, {
    a: {
        value: 1,
        enumerable: false
    }, 
    b: {
        value: 2,
        enumerable: true
    },
    c: {
        value: 3,
        enumerable: false
    }
})

obj.d = 4;

//等同于

//Object.defineProperty(obj, 'd', {
//    configurable: true,
//    enumerable: true,
//    writable: true,
//    value: 4
//})

for(var key in obj) {
    console.log(key);  
    // 打印一次b, 一次d, a和c属性enumerable为false,不可被枚举
} 

var arr = Object.keys(obj);
console.log(arr);  // ['b', 'd']
get and set

Simple two-way data binding

 //html
 <body>
     <p>
         input1=>
       <input type="text" id="input1">
     </p>
     <p>
         input2=>
         <input type="text" id="input2">
     </p>
     <div>
         我每次比input1的值加1=>
         <span id="span"></span>
     </div>
 </body>

 //js
 var oInput1 = document.getElementById('input1');
 var oInput2 = document.getElementById('input2');
 var oSpan = document.getElementById('span');
 var obj = {};
 Object.defineProperties(obj, {
     val1: {
         configurable: true,
         get: function() {
             oInput1.value = 0;
             oInput2.value = 0;
             oSpan.innerHTML = 0;
             return 0
         },
         set: function(newValue) {
             oInput2.value = newValue;
             oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0
         }
     },
     val2: {
         configurable: true,
         get: function() {
             oInput1.value = 0;
             oInput2.value = 0;
             oSpan.innerHTML = 0;
            return 0
         },
         set: function(newValue) {
             oInput1.value = newValue;
             oSpan.innerHTML = Number(newValue)+1;
         }
     }
 })
 oInput1.value = obj.val1;
 oInput1.addEventListener('keyup', function() {
     obj.val1 = oInput1.value;
 }, false)
 oInput2.addEventListener('keyup', function() {
     obj.val2 = oInput2.value;
 }, false)
Original link address: https://segmentfault.com/a/1190000011294519?utm_source=tag-newest#articleHeader15

Reproduced in: https: //www.jianshu.com/p/30d1afd1bb2c

Guess you like

Origin blog.csdn.net/weixin_33913377/article/details/91080538