看过博主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()
这个方法呢,我目前遇到的就是深拷贝实现时会使用,因为我们知道每个对象都有原型,而深拷贝时我们只是希望拷贝对象的自身属性,使用此方法做个区分就是非常奈斯的做法了。
好了,这篇文章就说到这里了,全文结束。