如何解决for in 循环无法遍历symbol key的问题

简介: 如何解决for in 循环无法遍历symbol key的问题

先说for in循环对象,hasOwnProperty()的作用

var obj = {
    name:"echolun",
    age:"24",
    sex:"male"
},
objName=[], //用来装对象属性名
objVal=[];  //用来装对象属性值
for(var i in obj){
    objName.push(i);
    objVal.push(obj[i]);
}
console.log(objName,objVal);

image.png

需要注意的是,for in循环对象会访问原型链上所有对象属性,看下面。

var obj = {
    name:"echolun",
    age:"24",
    sex:"male"
},
objName=[], //用来装对象属性名
objVal=[];  //用来装对象属性值
Object.prototype.game="lastgame";
for(var i in obj){
    objName.push(i);
    objVal.push(obj[i]);
}
console.log(objName,objVal);
}

这里同样是循环对象obj,但是需要注意的是,原型链上我们额外添加的对象game也被循环出来。

image.png

那么我们只想循环对应的对象该怎么做呢,这里引入hasOwnProperty()方法,hasOwnProperty()函数用于指示一个**对象自身(不包括原型链)**是否具有指定名称的属性。如果有,返回true,否则返回false。


说简单点,它能帮你指向你当前循环的对象,而过滤掉原型链上其它对象,因为在工作中我们很难保证其他人是否会修改原型链,这样做会更为保险,那么修改代码:

var obj = {
    name:"echolun",
    age:"24",
    sex:"male"
},
objName=[], //用来装对象属性名
objVal=[];  //用来装对象属性值
Object.prototype.game="lastgame";
for(var i in obj){
    if(obj.hasOwnProperty(i)) {
        objName.push(i);
        objVal.push(obj[i]);
    }
}
console.log(objName,objVal);
}

看吧,这下就过滤掉game了。


image.png


1.hasOwnProperty()函数用于指示一个对象自身(不包括原型链)是否具有指定名称的属性。如果有,返回true,否则返回false。

2.说简单点,它能帮你指向你当前循环的对象,而过滤掉原型链上其它对象,因为在工作中我们很难保证其他人是否会修改原型链,这样做会更为保险。

3.因为 for in 循环总是遍历整个原型链,所以当遍历多继承的对象时效率较低。

4.为了检查某个对象是否拥有不在原型链上的自定义属性,就有必要用到 hasOwnProperty 方法,任何一个对象都具有该方法,它继承自 Object.prototype。

5.当检测某个对象是否拥有某个属性时,hasOwnProperty 是唯一可以完成这一任务的方法,在 for in 循环时,建议增加 hasOwnProperty 进行判断,可以有效避免扩展本地原型而引起的错误。

6.我们无法完全检测某个属性是否是undefined,因为属性有可能存在,但其值为undefined。

7.hasOwnProperty 是Javascript中唯一一个可以处理对象属性而不遍历原型链的方法。

hasOwnProperty()的主要作用就是在多重循环中过滤掉不符合条件的对象,减少遍历次数,和其他编程语言中的continue和break类似。


image.png


属性名的遍历


Symbol 作为属性名,遍历对象的时候,该属性不会出现在 for...in 、 for...of 循环中,也不 会被 Object.keys() 、 Object.getOwnPropertyNames() 、JSON.stringify() 返回。


但是,它也不是私有属性,有一个 Object.getOwnPropertySymbols() 方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

.  const obj = {};
.  let a = Symbol('a');
.  let b = Symbol('b');
.
.  obj[a] = 'Hello';
.  obj[b] = 'World';
.
.  const objectSymbols = Object.getOwnPropertySymbols(obj);
.
.  objectSymbols
.  // [Symbol(a), Symbol(b)]

下面是另一个例子, Object.getOwnPropertySymbols() 方法与 for...in 循

环、 Object.getOwnPropertyNames 方法进行对比的例子。

.  const obj = {};
.  const foo = Symbol('foo');
.
.  obj[foo] = 'bar';
.
.  for (let i in obj) {
.  console.log(i); // 无输出
.  }
.
.  Object.getOwnPropertyNames(obj) // []
.  Object.getOwnPropertySymbols(obj) // [Symbol(foo)]

另一个新的 API, Reflect.ownKeys() 方法可以返回所有类型的键名,包括常规键名和 Symbol键名

.  let obj = {
.  [Symbol('my_key')]: 1,
.  enum: 2,
.  nonEnum: 3
.  };
.
.  Reflect.ownKeys(obj)
.  // ["enum", "nonEnum", Symbol(my_key)]

由于以 Symbol 值作为键名,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。


具体可以参考 https://www.cnblogs.com/zhenggc99/p/14718859.html



相关文章
|
4天前
|
小程序
小程序for循环中key值的作用?
小程序for循环中key值的作用?
|
6月前
Set的5种遍历方式
Set的5种遍历方式
|
6月前
HashMap遍历方式
HashMap遍历方式
|
4天前
|
存储 前端开发 索引
Map循环注意事项
Map循环注意事项
10 1
|
4天前
|
前端开发 程序员
【面试题】在循环 for、for-in、forEach、for-of 、map中改变item的值,会发生什么?
【面试题】在循环 for、for-in、forEach、for-of 、map中改变item的值,会发生什么?
|
8月前
|
小程序 JavaScript 索引
小程序v-for与key值使用
小程序v-for与key值使用
121 0
数组把key相同值,合并value值(整理)
数组把key相同值,合并value值(整理)
|
9月前
|
JavaScript 索引
v-for循环为什么要绑定key值
v-for循环为什么要绑定key值
80 0
|
10月前
|
存储 前端开发 索引
map循环注意事项
map循环注意事项
80 0