• for-in与不可枚举


    用for循环遍历对象

    var person = {
      name: 'tom',
      age: 29,
      sex: '男'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    首先有Object.keys()的方法,拿到可迭代(遍历)的私有属性名的集合(数组)

    var keys = Object.keys(person);
        for (var i = 0; i < keys.length; i++) {
        console.log(keys[i] + ":" + person[keys[i]]); 
            // 输出: name:tom   age: 29    sex: '男'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    但如果直接用 for…in 遍历可能会出现缺陷:
    for in 典型的缺陷:

    var arr = [1, 2, 3, 4];
    
    • 1

    正常情况:

    for (var i in arr) {
      console.log(i);
    } //输出 0 1 2 3
    
    • 1
    • 2
    • 3

    正常情况下我们输出的是没问题的;但是
    如果你给 Array添加了一个(判断元素是不是存在数组中)的新方法:

    Array.prototype.inArray = function () {
      for (var i = 0; i < this.length; i++) {
        if (this[n] === ele) {
        return true;
        }
      }
      return false;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后我们再试试 for…in ,看一看它还好不好使。

    for (var i in arr) {
      console.log(i);
    }//输出 0 1 2 3 inArray
    
    • 1
    • 2
    • 3

    为什么会多了一个inArray呢?因为它也被遍历出来了。

    for…in…会遍历到对象中所有可枚举的属性方法,我们给对象添加的方法默认也是可枚举的;
    自己添加的方法怎么样才能不被遍历到呢?
    于是我们就用到了 Object.defineProperty ()
    这个方法。
    该方法允许精确地添加或修改对象的属性。通过赋值操作修改,在枚举对象属性时会被枚举到(for…in 或 Object.keys方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。 (摘自:MDN web docs)
    此方法有四个属性:
    configurable
    当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 默认为 false。
    enumerable
    当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。 默认为 false。
    数据描述符还具有以下可选键值:
    value
    该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 默认为 undefined。
    writable
    当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。 默认为 false。
    (摘自:MDN web docs)
    看了这四个属性,我们就能很开心的解决上面的问题了:

          var arr = [1, 2, 3, 4];
            Array.prototype.inArray = function() {
                for (var i = 0; i < this.length; i++) {
                    if (this[n] === ele) {
                        return true;
                    }
                }
                return false;
            };
            //解决问题的代码
            Object.defineProperty(Array.prototype, 'inArray', {
                enumerable: false  //不可枚举(即不可遍历)
            })
    ​
    ​
            for (var i in arr) {
                console.log(i);
            } //输出 0 1 2 3 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    到此为止我们的问题就解决了!希望能帮助到大家!

  • 相关阅读:
    XMLPath的基本使用
    【数据结构】08排序
    解决电脑显示找不到msvcp140_CODECVT_IDS.dll文件的办法
    cs231n作业1——Softmax
    SpringBoot项目的搭建
    Struts.xml 配置文件说明
    GANs综述
    Kotlin的基本使用
    LeetCode-622. 设计循环队列
    go pprof 你真用对了吗
  • 原文地址:https://blog.csdn.net/sdasadasds/article/details/127733975