// Poisoning Object.prototypeObject.prototype.bar = 1;var foo = {goo: undefined};foo.bar; // 1'bar' in foo; // truefoo.hasOwnProperty('bar'); // falsefoo.hasOwnProperty('goo'); // true在這裡,只有hasOwnProperty 能給出正確答案,這在遍歷一個對象的屬性時是非常必要的。 Javascript 中沒有其他方法能判斷一個屬性是定義在對象本身還是繼承自原型鏈。
hasOwnProperty 作為屬性
Javascript 並未將hasOwnProperty 設為敏感詞,這意味著你可以擁有一個命名為hasOwnProperty 的屬性。這個時候你無法再使用本身的hasOwnProperty 方法來判斷屬性,所以你需要使用外部的hasOwnProperty 方法來進行判斷。
var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons'};foo.hasOwnProperty('bar'); // always returns false// Use another Object's hasOwnProperty and call it with 'this' set to foo({}).hasOwnProperty.call(foo, 'bar'); // true// It's also possible to use hasOwnProperty from the Object// prototype for this purposeObject.prototype.hasOwnProperty.call(foo, 'bar'); // true總結
當判斷對象屬性存在時,hasOwnProperty 是唯一可以依賴的方法。這裡還要提醒下,當我們使用for in loop 來遍歷對象時,使用hasOwnProperty 將會很好地避免來自原型對象擴展所帶來的困擾。
下面是其他網友的補充:
Javascript中Object對象原型上的hasOwnProperty()用來判斷一個屬性是定義在對象本身而不是繼承自原型鏈。
obj.hasOwnProperty(prop)
參數prop
要檢測的屬性字符串名稱或者Symbol(ES6)
o = new Object();o.prop = 'exists';o.hasOwnProperty('prop'); // 返回trueo.hasOwnProperty('toString'); // 返回falseo.hasOwnProperty('hasOwnProperty'); // 返回false使用hasOwnProperty作為某個對象的屬性名
因為javascript沒有將hasOwnProperty作為一個敏感詞,所以我們很有可能將對象的一個屬性命名為hasOwnProperty,這樣一來就無法再使用對象原型的hasOwnProperty 方法來判斷屬性是否是來自原型鏈。
var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons'};foo.hasOwnProperty('bar'); // 始終返回false不能使用該對象.hasOwnProperty 這種方法,怎麼來解決這個問題呢?我們需要使用原型鏈上真正的hasOwnProperty 方法:
({}).hasOwnProperty.call(foo, 'bar'); // true// 或者:Object.prototype.hasOwnProperty.call(foo, 'bar'); // true參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty