码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-04-07 00:44:05      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

  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>

  输出结果:

技术分享

  

 

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

标签:

原文地址:http://www.cnblogs.com/diligenceday/p/4394421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!