Believe that the students see this title when the face of a confused, what? JS can constant definition? Don't tease me, okay? To be exact, JS does not have a constant (ES6 as if there is a constant definition of the keyword), but in depth we can find JS a lot of unknown nature, good use of these properties, you will find a different JS World.
first, in js, The Object's properties also contain its own implicit nature, such as the following objects:
1 var obj = {};2 obj.a = 1;3 obj.b = 2;
Here we define an object, obj, and define the Object's two properties a, b, We can modify the values of the two properties, you can delete the two properties with the delete keyword, you can also use for ... in ... The statement enumerates all the properties of the obj object, these operations are called properties of the object property, we usually write the code when we unconsciously default these properties, they are considered as JS due to the nature, but these properties can actually be modified. I usually define the properties of the method, which defaults to the nature of the property, but we can also modify the properties when defining the properties, such as:
1 var obj = {}; 2 obj.a = 1; 3 OBJ.B = 2; 4 5//equivalent to 6 var obj = {7 a:1, 8 b:2 9}10 11//equivalent to the var obj = {};13 object.defineproperty (obj, "a", {14
value:1, //initial value of writable:true, //writable configurable:true, / /configurable to Enumerable:true ///enumerable 18}); Object.defineproperty (obj, "b", { value:2, //initial value writable:true, // writable configurable:true, //configurable enumerable:true //enumerable 24});
Here is a method, Object.defineproperty (), the method is the ES5 specification, the role of the method is to define a new property on the object, or modify an existing property of the object, and describe the property, return this object, we look at the browser compatibility:
features |
Firefox (Gecko) |
Chrome |
Internet Explorer |
Opera |
Safari |
Basic support |
4.0 (2) |
5 |
9 [1] |
11.60 |
5.1 [2] |
Or the IE8, if your project requirements compatible with IE8, then this method is not applicable, but IE8 also to the implementation of the method, can only be applied on the DOM object, and there are some unique places, here is not explained.
The Object.defineproperty () method can define the data description and storage description of an Object's properties, where we only speak the data descriptor, not the storage descriptor, and the data descriptor has the following options:
-
configurable
-
This property can be changed and deleted only if the Property's configurable is True.
描述符
The default is
false
.
-
enumerable
-
当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。
Default is
false。
-
value
-
The value that corresponds to the Property. can be any valid JavaScript value (numeric, object, function, etc.). The default is
undefined
.
-
writable
-
当且仅当该属性的 writable 为 true 时,该属性才能被
the assignment operator
改变。
defaults to
false
.
Note that when we define a property in the usual way, its data descriptor except value is true by default, and when we define the property with Object.defineproperty (), the default is False.
That is, when we set the writable to false, the property is read-only and satisfies the constant nature, and we enclose the constants in the const namespace:
1 var CONST = {};2 object.defineproperty (const, "A", {3 value:1,4 writable:false,//set Property read-only 5 configurable:t rue,6 enumerable:true7}); 8 Console.log (CONST. A); CONST. A = 2; Errors are thrown in strict mode, silently fails in non-strict mode, and the modification is INVALID.
But the constants defined in this way are not absolute, because we can still modify the property values by modifying the Property's data descriptor:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:false, 5 configurable:true, 6 Enumerable : True 7}); 8 Object.defineproperty (CONST, "A", {9 value:2,10 writable:true, //the writable State of the recovery attribute one by one configurable: true,12 Enumerable:true13}) Console.log (CONST. A); 215 CONST. A = 3;16 Console.log (CONST. A); 3
To achieve a true constant, you also need to set the property to not be configured:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:false, //set Property read-only 5 configurable:false, //settings Properties not configurable 6 enumerable:true 7}); 8 Console.log (CONST. A); 1 9 CONST. A = 2; Error! Attribute read-only object.defineproperty (CONST, "A", {one value:2,12 writable:true, configurable:true,14 enumerable:true15}); Error! property is not configurable
however, If you only set the property to a non-configurable state, you can still modify the property value:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:true, //set writable 5 configurable:false,< C19/>//settings Property not configurable 6 enumerable:true 7}); 8 Console.log (CONST. A); 1 9 CONST. A = 2;10 Console.log (CONST. A); 2
further, we can infer that the configurable descriptor freezes only the descriptor of the property, does not affect the property value, that is, the descriptor freezes the state of writable, configurable, enumerable, and does not limit the property value:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:false, //set not writable 5 configurable:false, //settings Property not configurable 6 Enumerable:false //set not enumerable 7}) 8 object.defineproperty (CONST, "A", {9 value:2, // The property itself is not affected by configurable, but because the property is not writable, the writable limit is writable:true, //error! property is not configurable one configurable:true, //error! property is not configurable for Enumerable:true //error! Property not configurable 13});
however, there is one exception to the configurable limitation, which is that writable can be changed from true to false and not from false to True:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:true, //set writable 5 configurable:false, / /settings Property not configurable 6 Enumerable:false //set not enumerable 7}); 8 Object.defineproperty (CONST, "A", {9 value:2, //the property itself is not affected by configurable, because the property is writable, the modification succeeds Writable:false , configurable:false, enumerable:false); console.log (CONST. A); 215 CONST. A = 3; Error! property is Read-only
An enumerable descriptor is used to configure whether a property can be enumerated, that is, whether it appears in the for ... In the Statement:
1 var CONST = {}; 2 object.defineproperty (CONST, "A", {3 value:1, 4 writable:false, 5 configurable:false, 6 Enumerable : True //enumerable 7}); 8 Object.defineproperty (CONST, "B", {9 value:2,10 writable:false,11 configurable:false,12 Enumerable:false //non-enumerable); (var key in CONST) { console.log (const[key]) ; 116};
With the above foundation, we also learn a method of defining constants, using the data descriptor of the property, the next time we need to use a constant, we can define a const namespace, the constant is encapsulated in the namespace, because the property description defaults false, So we can also define:
1 var CONST = {};2 object.defineproperty (CONST, "A", {3 value:1,4 enumerable:true5}); 6 Object.defineproperty (CONST, "B", {7 value:2,8 enumerable:true9});
The above method is to define a set of constants from the angle of the attribute, but we can also use another method to configure an object to include all its properties from the Object's point of view, and the Object.preventextensions () method can make an object non-extensible and the object cannot add new Properties. however, You can delete existing properties:
1 var const = {};2 Const. A = 1;3 CONST. B = 2;4 object.preventextensions (const); 5 Delete CONST. B;6 Console.log (CONST); Const: {a:1}7 Const. C = 3; Error! object is not extensible
On the basis of this method, we can use Object.seal () to seal an object, which blocks the object extension and sets all properties of the object to be non-configurable, but writable:
1 var CONST = {}; 2 CONST. A = 1; 3 CONST. B = 2; 4 Object.seal (CONST); 5 CONST. A = 3; 6 Console.log (CONST. A); 3 7 object.defineproperty (CONST, "B", {8 value:2, 9 writable:true, configurable:true, // Error! property is not configurable one enumerable:false, //error! Property cannot be configured with a ()) CONST. C = 3; Error! object is not extensible
This means that the Object.seal () method is equivalent to helping us to set the configurable descriptor of the property to False in bulk, so the code implementation level is equivalent to:
1 object.seal = function (obj) {2 object.preventextensions (obj); 3 for (var key in Obj) {4 object.defineprop Erty (obj, key, {5 value:obj[key], 6 writable:true, 7 configurable:false, 8 enumerable:true 9 }) 1 0 };11 return obj;12}
Based on the above two methods, we canObject.freeze() 来对一个对象进行冻结,实现常量的需求,该方法会阻止对象扩展,并冻结对象,将其所有属性设置为只读和不可配置:
1 var CONST = {}; 2 CONST. A = 1; 3 CONST. B = 2; 4 Object.freeze (CONST); 5 CONST. A = 3; Error! Property Read-only 6 Object.defineproperty (CONST, "B", {7 value:3, //error!) Property Read-only 8 writable:true, //error! Property not configurable 9 configurable:true, //error! property is not configurable for enumerable:false, //error! Property not configurable One}) . C = 3; Error! object is not extensible
From the code implementation level is equivalent to:
1 Object.freeze = function (obj) {2 object.preventextensions (obj); 3 for (var key in Obj) {4 Object.defin Eproperty (obj, key, {5 value:obj[key], 6 writable:false, 7 configurable:false, 8 enumerable: True 9 }) };11 return obj;12}
finally, let's look at the compatibility of these three methods:
Object.preventextensions ()
Feature |
Firefox (Gecko) |
Chrome |
Internet Explorer |
Opera |
Safari |
Basic Support |
4 (2.0) |
6 |
9 |
Not implemented |
5.1 |
Object.seal ()
Feature |
Firefox (Gecko) |
Chrome |
Internet Explorer |
Opera |
Safari |
Basic Support |
4 (2.0) |
6 |
9 |
Not implemented |
5.1 |
Object.freeze ()
Feature |
Firefox (Gecko) |
Chrome |
Internet Explorer |
Opera |
Safari |
Basic Support |
4.0 (2) |
6 |
9 |
12 |
5.1 |
In the end is also the evil ie, are incompatible IE8
now, we have two ways to define constants in js, the first method is implemented from the attribute level, you can continue to add more than one constant on the namespace, and the second method is implemented from the object plane, all the properties of the frozen object and the object Itself:
1//the First method: The attribute plane, the object can be extended 2 var CONST = {}; 3 Object.defineproperty (CONST, "A", {4 value:1, 5 enumerable:true 6}); 7 8//second method: Object plane, Object non-expandable 9 var CONS T = {};10 CONST. A = 1;11 Object.freeze (CONST);
About the JS constant problem is here, many books in the introduction of JS basis will be mentioned in JS there is no constant, resulting in many JS developers in the beginning of the default JS is no constant of this statement. In strict grammatical sense, JS does not have constant, but we can build our own constant by the depth of knowledge and creativity, knowledge is dead, people are alive, as long as we continue to explore, full of creativity, we will find a different world.
JavaScript constant Definition