美文网首页深究JavaScript
JS中可枚举属性(enumerable)和propertyIsE

JS中可枚举属性(enumerable)和propertyIsE

作者: 黑雷 | 来源:发表于2017-06-15 17:30 被阅读91次

    什么是可枚举属性

    枚举就是列举,可枚举属性就是可以列举的属性,直白一点就是可以用for in遍历到的属性。

    propertyIsEnumerable()的用法

    obj.propertyIsEnumerable(prop) 是用来判断属性是否可枚举的

    • obj: 要检测的对象
    • 参数 prop: 要检测的属性的名称。
    • 返回值: Boolean类型,可枚举属性的时候返回true。

    可枚举属性会对那些操作产生影响

    for…in
    Object.keys()
    JSON.stringify()

    下面我们详细测试一下

    1. 可枚举属性的遍历

    首先我们看一个栗子:

    var p = {name: '张三', age: 28};
    for (var key in p) {
        console.log('属性名:' + key + ',是否可枚举:' + p.propertyIsEnumerable(key));
    }
    //输出结果:
    //->属性名:name,是否可枚举:true
    //->属性名:age,是否可枚举:true
    

    p上的name和age两个属性都被遍历了,这两个属性都是可枚举属性,那什么是不可枚举属性呢?

    2. 不可枚举属性不会被遍历

    我们再看一个栗子:

    Object.prototype.get_name = function () {
        return this.name;
    };
    var p = new Object({name: '张三'});
    for (var key in p) {
        console.log('属性名:' + key + ',是否可枚举:' + p.propertyIsEnumerable(key));
    }
    //输出结果:
    // ->属性名:name,是否可枚举:true
    // ->属性名:get_name,是否可枚举:false
    

    可能有疑问get_name判断可枚举返回的是false怎么还遍历出来了呢?其实正确的理解是这样的, get_name不是实例p的属性是Object原型上的属性,对于实例p来说是不可枚举的,但是对于原型来说是可枚举的(下面代码有测试)。(for…in遍历,只要在遍历对象和对象所在的原型链上的可枚举属性都会被遍历)
    大家想一个问题,get_name是Object的原型上的属性,被遍历了。Object的原型上还有很多的属性,有toString、hasOwnProperty还有我们现在正在研究的propertyIsEnumerable都是原型上的属性,怎么就只有自定义的get_name被遍历出来了呢?因为其它属性都是不可枚举的。看下面代码:

    console.log(p.__proto__.propertyIsEnumerable('get_name'));//->true
    console.log(p.__proto__.propertyIsEnumerable('toString'));//->false
    console.log(p.__proto__.propertyIsEnumerable('propertyIsEnumerable'));//->false
    console.log(p.__proto__.propertyIsEnumerable('hasOwnProperty'));//->false
    

    我们已经知道了什么是可枚举属性,知道了propertyIsEnumerable得用法,我们可不可以自定义一个不可枚举属性呢?当然可以。

    3. 自定义不可枚举属性

    var p = new Object({name: '张三'});
    //为p设置不可枚举属性
    Object.defineProperty(p, "age", {
        value: 20,
        enumerable: false
    });
    for (var key in p) {
        console.log('属性名:' + key + ',是否可枚举:' + p.propertyIsEnumerable(key));
    }
    //输出结果:属性名:name,是否可枚举:true
    console.log('age是不是p的可枚举属性:' + p.propertyIsEnumerable('age')+',age属性的值是多少:'+ p.age);
    //age是不是p的可枚举属性:false,age属性的值是多少:20
    

    通过defineProperty我们就自定义了一个不可枚举的属性,并且可以正常使用。

    4. 不可枚举属性对Object.keys()和JSON.stringify()的影响

    Object.keys()和JSON.stringify()也不会列举出不可枚举属性,也不会列举出原型链上的所有属性。

    Object.prototype.get_name = function () {};
    var p = new Object({name: '张三'});
    //为p设置不可枚举属性
    Object.defineProperty(p, "age", {
        value: 20,
        enumerable: false
    });
    console.log(Object.keys(p));//输出结果->["name"]
    console.log(JSON.stringify(p));//输出结果->{"name":"张三"}
    

    如果文档哪里不正确欢迎指正。
    本文主要参考文档:http://www.cnblogs.com/kongxy/p/4618173.html
    欢迎转载,但请注明出处。

    相关文章

      网友评论

      • 6e8ea646d031:今天刚好学到这里,看了你的讲解,更明白了👍👍👍👏👏👏

      本文标题:JS中可枚举属性(enumerable)和propertyIsE

      本文链接:https://www.haomeiwen.com/subject/coquqxtx.html