继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

JavaScript 对象属性的存在性

萧十郎
关注TA
已关注
手记 309
粉丝 36
获赞 166

先看一个例子

var person = {  name:undefined}console.log(person.name); // undefinedconsole.log(person.age); // undefined

上面的例子中 person对象有一个name属性,没有age属性。但是,使用
person.name 和 person.age访问属性值时,两者的结果都是undefined。

因此我们没法通过值为undefined来判断一个对象是否有某个属性。

那么如何判断一个对象是否存在一个属性。

1. in 操作符

如果指定的属性存在对象或其原型链中,那么in操作符返回true 。

注意: in操作符判断属性的存在性,不论属性是否可枚举

举个例子:

let man = {  speak: 'I can'}// 已man对象为原型创建person对象let person = Object.create(man);//定义person对象的name属性,该属性是person对象的自有属性person.name='noshower';//定义person对象的自有属性,但是'age'不可枚举,Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});console.log('speak' in person);  // trueconsole.log('name' in person);   // trueconsole.log('age' in person);   // trueconsole.log('job' in person);   // false

因为job不存在person中,也不存在person对象的原型链上,所以结果为false。

再看个例子:

var array = new Array('a','b','c','d','e');delete array[3];
console.log(3 in array); // falseconsole.log(array.length); // 5

从这个例子中看出,当删除数组的某个下标后,数组下标确实不存在了。但是没有改变数组的长度。只是该位置被空出来了而已。

2. hasOwnProperty

如果对象自身属性中存在指定的属性,那么hasOwnProperty()方法将会返回true,否则返回false。

注意:

  • hasOwnProperty 不会检查对象原型链上的属性。

  • hasOwnProperty 不论属性是否可以枚举

  • hasOwnProperty方法存在于Object.prototype上,因此只要对象的原型链上存在Object.prototype, 就可以直接访问hasOwnProperty方法。有点对象(通过Object.create(null)创建的对象)没有连接到Object.prototype,那么就无法访问到hasOwnProperty方法。

  • JavaScript 没有保护hasOwnProperty属性名,因此,任何对象都可以使用hasOwnProperty这个名字作为属性名。

  • 上述两点,所以可必要使用Object.prototype.hasOwnProperty.call(obj,prop)这种形式判断某个属性的存在, 这样就无需担心obj上是否存在hasOwnProperty方法或者hasOwnProperty被覆盖的问题。

举个例子:

let man = {  speak: 'I can'}let person = Object.create(man);

person.name='noshower';Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});console.log(person.hasOwnProperty('speak')); // falseconsole.log(person.hasOwnProperty('name')); // trueconsole.log(person.hasOwnProperty('age')); // trueconsole.log(person.hasOwnProperty('job')); // false

因为speak属性存在于原型链上,所以返回false。
因为name属性是自有属性,所以返回true。
因为age属性是自有属性,虽然该属性不可枚举,但结果还是true。
因为job属性不存在,所以没有false。

3. for...in 循环

for...in 循环用来遍历对象的可枚举属性,包括原型链上的

注意:

  • for..in 循环以任意顺序迭代一个对象的属性,不同浏览器遍历属性的顺序可能不同。 因此,最好不要在迭代中对对象进行添加、修改或删除属性。

  • 不要使用for..in遍历数组

  • for...in不会返回不可枚举的属性

举个例子:

let man = {  speak: 'I can'}let person = Object.create(man);

person.name='noshower';Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});for(let prop in person){  console.log(prop);   // name , speak (并不一定是这样的输出顺序)}

其中age属性没有遍历得到,因为它是不可枚举的。

4. propertyIsEnumerable

如果一个属性是对象的自有属性(直接定义在对象上的)且该属性可枚举,那么 propertyIsEnumerable方法返回true,否则返回false。

举个例子:

let man = {  speak: 'I can'}let person = Object.create(man);

person.name='noshower';Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});console.log(person.propertyIsEnumerable('speak')); //falseconsole.log(person.propertyIsEnumerable('name')); // trueconsole.log(person.propertyIsEnumerable('age')); // false

5. Object.keys()

Object.keys() 方法会返回一个由给定对象的所有自身可枚举属性组成的数组。

注意:

  • Object.keys() 返回的属性是可枚举

  • Object.keys()返回的属性是对象的自有属性

  • 结果数组中属性名的排列顺序和使用 for ...in循环遍历该对象时返回的顺序一致

举个例子:

let man = {  speak: 'I can'}let person = Object.create(man);

person.name='noshower';Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});console.log(Object.keys(person)); // [ 'name' ]

6. Object.getOwnPropertyNames()

Object.getOwnPropertyNames()方法会返回一个数组,包含所有自有属性,无论它们是否可枚举。

注意:

  • 返回的是自有属性

  • 不论是否可枚举

  • 不包括Symbol值作为名称的属性

  • 数组中可枚举属性的顺序与通过for...in循环(或Object.keys)迭代该对象属性时一致。数组中不可枚举属性的属性未定义。

举个例子:

let man = {  speak: 'I can'}let person = Object.create(man);

person.name='noshower';Object.defineProperty(person, 'age', {  enumerable: false,  configurable: true,  writable: true,  value: 23});console.log(Object.getOwnPropertyNames(person)); //[ 'name', 'age' ]

7.自定义函数:getOwnInnumerablePropertyNames

getOwnInnumerablePropertyNames 只获取对象自身的所有不可枚举属性

function getOwnInnumerablePropertyNames (obj){    //返回对象的所有自有属性,包括不可枚举的
    let props = Object.getOwnPropertyNames(obj);    //返回对象的所有可枚举属性
    let propsEnum = Object.keys(obj); 
    // 过滤出所有不可枚举的
    return props.filter(function(key){      return propsEnum.indexOf(key) === -1;
    })
}

参考文献

  • 《你不知道的JavaScript 上卷》



作者:我待前端如初恋
链接:https://www.jianshu.com/p/c75992ee7b2c


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP