壹 ❀ 引
看過博主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()這個方法呢,我目前遇到的就是深拷貝實現時會使用,因為我們知道每個對象都有原型,而深拷貝時我們只是希望拷貝對象的自身屬性,使用此方法做個區分就是非常奈斯的做法了。
好了,這篇文章就說到這里了,全文結束。
