听风是风

学或不学,知识都在那里,只增不减。

导航

JS 判断对象属性是否存在,判断是否包含某个属性,是否为自身属性

壹 ❀ 引

看过博主JS 疫情宅在家,学习不能停,七千字长文助你彻底弄懂原型与原型链这篇文章的同学应该知道,文中有专门介绍这个问题。那么为什么我要另起一篇再说一次呢?原因有两个,一是介绍原型与原型链的文章过长,大家不一定看得完;二是这个月我只写了一篇博客!!!我良心过不去!!我对不起关注我的粉丝!!!真实原因是,我发现网上问这个问题的人还挺多,单独拿出来说也值得(其实就是水文章),那么本文开始。

贰 ❀ 判断是否包含某对象

我们知道访问对象属性有两种形式,如下:

var obj = {
  name:'听风是风'
};
obj.name;//听风是风
obj['name'];//听风是风

那么马上有同学就想到用这两种形式判断对象是否包含某个属性,因为原型链上如果某个属性不存在就会返回undefined,比如:

if(!obj.age){
    console.log('obj没有age属性');
}

这么做行不行,行,但是存在缺陷。最特殊的情况就是我们有age字段,而它的值偏偏就是undefined,那这样就尴尬了。

怎么办呢,一般推荐使用 in 运算符,用法是属性名 in 对象,如果存在返回true,反之为false,来看个例子:

var echo = {
    name:'听风是风',
    job:undefined
};
console.log('name' in echo);//true
console.log('job' in echo);//true
console.log('age' in echo);//false

但需要注意的是,in 只能判断对象有没有这个属性,无法判断这个属性是不是自身属性,啥意思?咱们接着说。

叁 ❀ 判断是否是自身属性

一个最简单的构造函数创建实例的例子:

function Parent(){
    this.name = 'echo';
};
Parent.prototype.age = 26;
var o = new Parent();
o.name//echo
o.age//26

在这个例子中,对于实例 o 而言,name就是是自身属性,这是它自己有的,而age是原型属性,o虽然没有这个属性,但在需要时,它还是顺着原型链找到了自己的老父亲Parent,并借用了这个属性。

所以当我们用 in 判断时可以发现结果均为true:

'name' in o;//true
'age' in o;//true

针对这个问题,如果我们还要判断是否是自身属性,就得借用方法hasOwnProperty(),不信你看:

o.hasOwnProperty('name');//true
o.hasOwnProperty('age');//false

说到底hasOwnProperty()做了两件事,除了判断对象是否包含这个属性,还判断此属性是不是对象的自身属性。

所以我们可以简单总结一下,如果我们只需判断对象有没有某个属性,使用 in 运算符就好了。而如果我们还要关心这个属性是不是自身属性,那么推荐hasOwnProperty()方法。

说了这么多,这两个判断有什么使用场景呢?

关于 in 运算符判断对象有没有某个属性,最常见的,我们希望给某个对象添加一个方法,直接添加又担心其他同事已经声明过,存在覆盖的可能性,所以使用 in 来判断,没有这个属性,咱们再加。

当然针对这个问题,使用Symbol来确保对象key的唯一性也是不错的做法,这个就看实际场景了。

而关于hasOwnProperty()这个方法呢,我目前遇到的就是深拷贝实现时会使用,因为我们知道每个对象都有原型,而深拷贝时我们只是希望拷贝对象的自身属性,使用此方法做个区分就是非常奈斯的做法了。

好了,这篇文章就说到这里了,全文结束。

posted on 2020-02-28 20:16  听风是风  阅读(19546)  评论(2编辑  收藏  举报