hasOwnProperty vs propertyIsEnumerable

Sal*_*ali 20 javascript prototype

任何人都可以启发我,hasOwnProperty和propertyIsEnumerable有什么区别:

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

创建对象的实例:

var o = new f();
Run Code Online (Sandbox Code Playgroud)

在这里,我看不出差异.在我看来,他们正在做同样的事情

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
Run Code Online (Sandbox Code Playgroud)

如果我错了,请找我

Poi*_*nty 30

"propertyIsEnumerable"函数始终排除不会true为"hasOwnProperty" 返回的属性.你没有做任何事情来使任何属性都不可枚举,所以在你的测试中结果是一样的.

您可以使用"defineProperty"来定义不可枚举的属性; 在MDN上看到这个参考.

Object.defineProperty(obj, "hideMe", { value: null, enumerable: false });
Run Code Online (Sandbox Code Playgroud)

这就像:

obj.hideMe = null;
Run Code Online (Sandbox Code Playgroud)

除了属性不会出现在for ... in循环中,并且propertyIsEnumerable将返回测试false.

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


T.J*_*der 25

hasOwnPropertytrue即使对于不可枚举的"自有"属性(如length在一个中Array)也将返回.propertyIsEnumerabletrue仅返回可枚举的 "自己的"属性.("可枚举"属性是一个显示在for..in循环中的属性.)

例:

var a = [];
snippet.log(a.hasOwnProperty('length'));       // "true"
snippet.log(a.propertyIsEnumerable('length')); // "false"
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)

或者使用非数组对象:

var o = {};
Object.defineProperty(o, "foo", { enumerable: false });
snippet.log(o.hasOwnProperty('foo'));       // "true"
snippet.log(o.propertyIsEnumerable('foo')); // "false"
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)

(当你使用时Object.defineProperty,enumerable默认为false,但为了清楚起见,我在上面已明确说明.)


nop*_*ole 6

简单地说:

hasOwnProperty当且仅当属性是对象的属性且不被继承时,才返回true.这个很简单.

propertyIsEnumerable当且仅当hasOwnProperty返回true且属性可枚举时才返回true.因此propertyIsEnumerable,在hasOwnProperty测试之上是一个"附加要求",propertyIsEnumerable如果是,则名称会更准确hasOwnPropertyAndIsEnumerable.

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