2012-06-10 32 views
18

誰能開導我,是什麼 hasOwnProperty和propertyIsEnumerable的區別是:創建一個對象實例hasOwnProperty VS propertyIsEnumerable

function f(){ 
    this.a = 1; 
    this.b = 2; 
    this.c = function(){} 
} 
f.prototype = { 
    d : 3, 
    e : 4, 
    g : function(){} 
} 

var o = new f(); 

在這裏,我看不出差別。 在我看來,他們都在做同樣的事情

o.hasOwnProperty('a'); //true 
o.hasOwnProperty('b'); //true 
o.hasOwnProperty('c'); //true 
o.hasOwnProperty('d'); //false 
o.hasOwnProperty('e'); //false 
o.hasOwnProperty('g'); //false 

o.propertyIsEnumerable('a'); //true 
o.propertyIsEnumerable('b'); //true 
o.propertyIsEnumerable('c'); //true 
o.propertyIsEnumerable('d'); //false 
o.propertyIsEnumerable('e'); //false 
o.propertyIsEnumerable('g'); //false 

右鍵我,如果我錯了

回答

27

的「propertyIsEnumerable」功能總是排除會不是「hasOwnProperty」返回true性能。你沒有做任何事情使任何屬性不可枚舉,所以在你的測試中結果是一樣的。

您可以使用「defineProperty」來定義屬性而不是 enumerable; MDN上的see this reference

Object.defineProperty(obj, "hideMe", { value: null, enumerable: false }); 

這就像:

obj.hideMe = null; 

除了屬性不會在for ... in循環出現,並與propertyIsEnumerable測試將返回false

這整個主題是關於擁有不老的瀏覽器可用,如果不是很明顯。

3

不同的是,propertyIsEnumerable返回true只有在財產存在,如果有可能的財產做ForIn,hasOwnProperty會如果屬性存在,返回true,不管到ForIn支持

從MSDN:

如果proName存在於 對象,並且可以使用一個ForIn環被枚舉

的propertyIsEnumerable方法返回true。如果對象沒有指定名稱的 財產或者指定的屬性不是 枚舉的 propertyIsEnumerable方法返回false。典型地,預定義的屬性是不可枚舉而 用戶定義的屬性總是枚舉的。如果對象具有 指定名稱的屬性,虛假的,如果它不

的hasOwnProperty方法返回true。此方法不檢查該對象的原型鏈中是否存在屬性 ;財產必須 是對象本身的成員。

20

hasOwnProperty將返回true甚至不可枚舉的 「自己」 的屬性(如在Arraylength)。 propertyIsEnumerable將只枚舉「自己」的屬性返回true。 (「enumerable」屬性是在for..in loops等中顯示的屬性。)

實施例:

var a = []; 
 
snippet.log(a.hasOwnProperty('length'));  // "true" 
 
snippet.log(a.propertyIsEnumerable('length')); // "false"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

或者與非數組對象:

var o = {}; 
 
Object.defineProperty(o, "foo", { enumerable: false }); 
 
snippet.log(o.hasOwnProperty('foo'));  // "true" 
 
snippet.log(o.propertyIsEnumerable('foo')); // "false"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

(當使用Object.definePropertyenumerable默認爲false,但我上面已經明確爲清楚起見)

+0

這個解釋是不是接受的答案清晰。 – mareoraft

5

簡單地說:

hasOwnProperty將返回true當且僅當該屬性是對象的屬性,而不是遺傳。這個很簡單。

propertyIsEnumerable將返回true當且僅當hasOwnProperty返回true並且屬性可以枚舉。所以propertyIsEnumerablehasOwnProperty測試之上的一個「附加要求」,如果它是hasOwnPropertyAndIsEnumerable,名稱propertyIsEnumerable會更準確。

演示:http://jsfiddle.net/aby3k/

+0

感謝您的簡要總結!所以,當我想要特別嚴格時,我會使用propertyIsEnumerable - 然後不需要hasOwnProperty。我一直在看「hasOwnProperty」在過濾「key in obj」循環時使用了很多,但很少使用「propertyIsEnumerable」... –