ECMA-262 defines some internal-use attributes to implement the javascript engine.Generally,these attributes are background-work some like the garbage-clear function,so they are not accessible directly.
Attributes of Data-property
There are four attributes controlling the behavior of data properties.(two pairs of square brackets indicates an internal attributes)
- [[configurable]] -- Indicates if the property may be redefined by removing the property
via delete, changing the property’s attributes, or changing the property into an accessor
property. By default, this is true for all properties defined directly on an object. - [[enumerable]] -- Indicates if the property will be returned in a for-in loop. By default,
this is true for all properties defined directly on an object. - [[writable]] -- Indicates if the property’s value can be changed. By default, this is true
for all properties defined directly on an object. - [[value]] -- Contains the actual data value for the property. This is the location from
which the property’s value is read and the location to which new values are saved. The
default value for this attribute is undefined.
Display
Method
Object.getOwnPropertyDescriptor() is used to read these attributes.Pay attention to the function
DisplayAtts().
var person = {
name: "Nicholas"
};
var namex;
function DisplayAtts(obj,proverty)
{
var descriptor=Object.getOwnPropertyDescriptor(obj,proverty);
var _str="value:"+String(descriptor.value);
_str+="\nconfigurable:"+descriptor.configurable.toString();
_str+="\nenumerable:"+descriptor.enumerable.toString();
_str+="\nwritable:"+descriptor.writable.toString();
alert(_str);
}
DisplayAtts(person,"name");//Nicholas,true,true,true
delete namex;
DisplayAtts(window,"namex");//undefined,false,true,true
Do you notice that the configurable of variable
namex is false?Generally, defined a global variable via
var notation can not be removed by delete notation as well as a object(you cannot delete "person").(
There is a BUG in Chrome: when you change the "namex" to "name", the second DisplayAtts will show a true configurable and you can not delete it.)
Reset
Method
Object.defineProperty() is used to changed the values of these attributes.
var person = {name:"Nicholas"};
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"
Writable set to false,so the value cannot be changed.Definition is the major ability of this method,the code upside can be rewritten as following:
var person={};
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});//defining the name property with method defineProperty and indicating attributes as well
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"
Accessor Properties
Setter and Getter function is familiar to programmers know java or C#.Yes,there is same concept in javascript.
Accessor properties don't have a value but getter and setter functions.When read value from the accessor property,the getter function is called automatically which returns a valid value.And when a value is written to an accessor property,the setter function is called to deal with the data.
There are four attributes of accessor properties as well:
There are four attributes of accessor properties as well:
- [[Configurable]] — Indicates if the property may be redefined by removing the property
via delete, changing the property’s attributes, or changing the property into a data
property. By default, this is true for all properties defined directly on an object. - [[Enumerable]] — Indicates if the property will be returned in a for-in loop. By default,
this is true for all properties defi ned directly on an object. - [[Get]] — The function to call when the property is read from. The default value is
undefined. - [[Set]] — The function to call when the property is written to. The default value is
undefined.
Display
Object.getOwnPropertyDescriptor() is used to read these attributes as well as data properties.Few changes makes the function
DisplayAtts() displays the
acceccor properties.
var programmer={name:"Addidas"};
function DisplayAtts(obj,proverty)
{
var descriptor=Object.getOwnPropertyDescriptor(obj,proverty);
var _str="configurable:"+descriptor.configurable.toString();
_str+="\nenumerable:"+descriptor.enumerable.toString();
_str+="\nget:"+String(descriptor.get);
_str+="\nset:"+String(descriptor.set);
alert(_str);
}
DisplayAtts(programmer,"name");//true,true,undefined,undefined
Reset
Now,reuse the function DisplayAtts mentioned above.var add = {
num1: 1,
num2: 2
};
Object.defineProperty(add, "result", {
get: function(){
return this.num1+this.num2;
}
});
add.num1 = 3;
add.result=20;
alert(add.result);//5
DisplayAtts(add,"result");//configurable:false enumerable:false get:function (){return this.num1+this.num2;} set:undefined
The
configurable and
enumerableis false as default,it means that once you defined
accessor properties ,you cannot configure them anymore.
Enumerable and for-in loop
You may use foreach loop in C# which is used to get every member of a list or something else implement enumerable interface,so you may be confused in javascript with the similar concepts: f
or-in loop and
enumerable property.
The truth is they are absolutely different.For-in loop in javacript is used to show the properties' name of object with a boolean true enumerable property just as the followings.
var person={};
Object.defineProperty(person, "name", {
configurable:false,
writable: false,
value: "Nicholas",
enumerable:false
});
Object.defineProperty(person,"age",{
writeable:true,
value:16,
enumerable:true
});
for ( x in person )
{
console.info(x+"\n");
}//It only show the 'age'(it's the name of property: age ,not 16),because it's enumerable