先说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);
需要注意的是,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也被循环出来。
那么我们只想循环对应的对象该怎么做呢,这里引入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了。
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类似。
属性名的遍历
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