ECMA5弄了一个新东西, 就是用户能够经过Object.defineProperty配置属性的可写,可配置,可枚举, 让咱们开发者能够定义一些属性,这些属性有点像native的赶脚html
好比,咱们日常定义一个对象这样子就能够了;chrome
var obj0 = { name : "nono" };
咱们也能够用新的方式,Object的属性设置方法defineProperty设置属性, 若是用户没有传enumberable, configurable, writable的值, 默认是false, 也就是说默认是没法枚举,没法配置, 没法可写的:this
var obj1 = {}; Object.defineProperty(obj1, "name",{ writable : false, configurable : false, enumerable : false, value : "nono" });
这个配置是不可写的,因此把对象obj1的name从新定义无效,(在ecma的严格模式报错);spa
<html> <body> <script> var obj1 = {}; Object.defineProperty(obj1, "name",{ writable : false, value : "nono" }); console.log("个人名字是: "+ obj1.name); //从新定义名字; obj1.name = "qihao"; //删除名字 delete obj1.name; console.log("个人新名字是: "+ obj1.name); </script> </body> </html>
这个是打印出来的结果:,声明咱们删除和从新定义名字的代码没生效, 由于writable是false;3d
咱们把元素的writable的配置从true改到false,再改到true,会报错code
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj1 = {}; Object.defineProperty(obj1, "favor",{ writable : true, value : "poppin" }); Object.defineProperty(obj1, "favor",{ writable : false, value : "readBook" }); try{ //若是从新定义可写属性从false到true会报错; Object.defineProperty(obj1, "favor",{ writable : true, value : "poppin" }); }catch(e) { console.log( "definedProperty error" + e ); } </script> </body> </html>
,由于默认的configurable是false, 因此从新配置writable报错了;htm
如今的cofigurable派上用场了:对象
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj1 = {}; Object.defineProperty(obj1, "favor",{ writable : true, configurable : true, value : "poppin" }); console.log( obj1.favor ); Object.defineProperty(obj1, "favor",{ writable : false, configurable : true, value : "readBook" }); console.log( obj1.favor ); try{ //由于configurable为true了,因此从新定义favor的writable不会报错; Object.defineProperty(obj1, "favor",{ writable : true, value : "poppin" }); }catch(e) { console.log( "definedProperty error" + e ); }; console.log( obj1.favor ); </script> </body> </html>
结果是:blog
也就是咱们经过配置configurable为true, 那么随时要更改enumerable,value, writable的配置为false或者true都没有问题;ip
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj1 = {}; Object.defineProperty(obj1, "favor",{ enumerable : false, value : "poppin" }); Object.defineProperty(obj1, "age", { value : 27 }); Object.defineProperty(obj1, "weight",{ "value" : 64, enumerable : true }); for(var p in obj1)console.log( p ); </script> </body> </html>
就输出了weight这个属性, favor和age这两个属性没有枚举到;
Object.getOwnPropertyDescriptor能够获取详细的描述, 不过仍是没有native的牛逼....;
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj1 = {}; Object.defineProperties(obj1,{ x : {value : "x"}, y : {enumerable : true}, z : {writable : true} }); for(var p in obj1)console.log( p ); </script> </body> </html>
经过defineProperties能够一次定义多个属性, 方便快捷
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj = {}; Object.defineProperty(obj, "name", { set : function(name) { this._name = name+" afterfix"; }, get : function() { return "prefix " + this._name; } }); obj.name = "nnnn"; console.log( obj.name ); </script> </body> </html>
在ecma5标准未被采纳以前,大多数js解释引擎实现了非标准的get,set方法, chrome下如今还有这些方法:
<html> <head> <meta charset="utf-8" /> </head> <body> <script> var obj = {}; obj.__defineGetter__("g", function() { return this._g+"__"; }); obj.__defineSetter__("g", function(arg) { this._g = arg; }); </script> </body> </html>
输出结果: