首页 > 网站 > WEB开发 > 正文

属性类型:数据类型,访问器类型的坑

2024-04-27 14:11:13
字体:
来源:转载
供稿:网友

属性类型:数据类型,访问器类型的坑

  ECMA5弄了一个新东西, 就是用户可以通过Object.definePRoperty配置属性的可写,可配置,可枚举, 让我们开发者可以定义一些属性,这些属性有点像native的赶脚

  比如,我们平常定义一个对象这样子就可以了;

var obj0 = {    name : "nono"};

  我们也可以用新的方式,Object的属性设置方法defineProperty设置属性, 如果用户没有传enumberable, configurable, writable的值, 默认是false, 也就是说默认是无法枚举,无法配置, 无法可写的:

var obj1 = {};Object.defineProperty(obj1, "name",{    writable : false,    configurable : false,    enumerable : false,    value : "nono"});

  writable

  这个配置是不可写的,所以把对象obj1的name重新定义无效,(在ecma的严格模式报错);

<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;

  我们把元素的writable的配置从true改到false,再改到true,会报错

<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>

  ,因为默认的configurablefalse, 所以重新配置writable报错了;

  

  configurable

  现在的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>

结果是:

  也就是我们通过配置configurable为true, 那么随时要更改enumerable,value, writable的配置为false或者true都没有问题;

  enumerable

<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

  Object.getOwnPropertyDescriptor可以获取详细的描述, 不过还是没有native的牛逼....;

  

  Object.defineProperties

<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可以一次定义多个属性, 方便快捷

  访问器属性,get, set

<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>

  old get,set,非标准的Getter,Setter方法

  在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>

  输出结果:

  


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表