hasOwnProperty vs propertyIsEnumerable

时间:2012-06-10 13:08:01

标签: javascript prototype

任何人都可以启发我,有什么区别 hasOwnProperty和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

如果我错了,请帮我

4 个答案:

答案 0 :(得分:30)

" propertyIsEnumerable"函数总是排除不会为" hasOwnProperty"返回true的属性。您没有做任何事情来使任何属性都不可枚举,因此在您的测试中结果是相同的。

您可以使用" defineProperty"定义可枚举的属性; MDN see this reference

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

那就像:

obj.hideMe = null;

除了财产不会显示在for ... in循环中,而propertyIsEnumerable的测试将返回false

这个主题是关于旧浏览器中没有的功能,如果这些功能不明显的话。

答案 1 :(得分:25)

hasOwnProperty即使对于不可枚举的“自有”属性(例如true中的length)也会返回ArraypropertyIsEnumerable仅会为可枚举的“拥有”属性返回true。 (“可枚举”属性是显示在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.defineProperty时,enumerable默认为false,但为了清晰起见,我已在上面明确说明。)

答案 2 :(得分:6)

简单说明:

  当且仅当属性是对象的属性且未被继承时,

hasOwnProperty将返回true。这个很简单。

  当且仅当propertyIsEnumerable返回true且属性可枚举时,

hasOwnProperty才会返回true。因此propertyIsEnumerablehasOwnProperty测试之上的一个“附加要求”,如果propertyIsEnumerable,则hasOwnPropertyAndIsEnumerable名称会更准确。

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

答案 3 :(得分:4)

不同之处在于propertyIsEnumerable仅在属性存在时才返回true,并且如果可以在属性上执行ForIn,则无论ForIn支持如何,hasOwnProperty都将返回true

来自MSDN:

  

如果proName存在,propertyIsEnumerable方法返回true   object,可以使用ForIn循环枚举。该   如果object没有,propertyIsEnumerable方法返回false   指定名称的属性,或者指定的属性不是   枚举。通常,预定义属性不可枚举   用户定义的属性始终是可枚举的。

     

如果object具有属性,则hasOwnProperty方法返回true   指定的名称,如果不是则为false。此方法不检查是否   该属性存在于对象的原型链中;财产必须   成为对象本身的一员。