2012-06-10 2 views
18

Может кто-нибудь просветить меня, в чем разница между hasOwnProperty и propertyIsEnumerable: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 

Правый меня, если я ошибаюсь

ответ

27

Функция «propertyIsEnumerable» всегда исключает свойства, которые не возвращают true для «hasOwnProperty». Вы ничего не сделали, чтобы какие-либо свойства не были перечислены, поэтому в вашем тесте результаты одинаковы.

Вы можете использовать "defineProperty" для определения свойств не enumerable; see this reference на MDN.

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

Это как:

obj.hideMe = null; 

за исключением имущества, не будут отображаться в for ... in петлями, и тесты с propertyIsEnumerable вернутся false.

Вся эта тема посвящена функциям, недоступным в старых браузерах, если это не очевидно.

3

Разница заключается в том, что propertyIsEnumerable возвращает истину, только если свойство существует, и если это возможно сделать Форин на имущество, hasOwnProperty возвращает истину, если свойство существует независимо для поддержки Форин

Из MSDN:

Метод propertyIsEnumerable возвращает true, если proName существует в объекте и может быть перечислены с использованием цикла ForIn. Свойство свойство IsEnumerable возвращает false, если объект не имеет свойства указанного имени или если указанное свойство не равно , перечислимым. Как правило, предопределенные свойства не перечисляются, тогда как пользовательские свойства всегда перечисляются.

Метод hasOwnProperty возвращает true, если объект имеет свойство , указанное имя, false, если оно отсутствует. Этот метод не проверяет, существует ли свойство в цепочке прототипов объекта; свойство должно быть членом самого объекта.

20

hasOwnProperty возвратит true даже для не-перечислимых "собственные" свойства (как length в качестве Array). propertyIsEnumerable вернет 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, но я был явно выше для ясности)

+0

Это объяснение яснее, чем принято отвечать. – mareoraft

5

Проще говоря:.

hasOwnProperty возвращает истину, если и только если свойство является свойством объекта и не является по наследству. Это просто.

и

propertyIsEnumerable возвращает истину, если и только если hasOwnProperty возвращает истину и свойство перечисляемость. Таким образом, propertyIsEnumerable является одним из «дополнительных требований» в верхней части теста hasOwnProperty, а имя propertyIsEnumerable было бы более точным, если оно hasOwnPropertyAndIsEnumerable.

демо: http://jsfiddle.net/aby3k/

+0

Спасибо за краткое описание! Таким образом, я буду использовать свойствоIsEnumerable, когда я хочу быть слишком строгим - hasOwnProperty не нужен тогда. Я видел, что «hasOwnProperty» много использовал при фильтрации «ключей в obj», но редко «propertyIsEnumerable» ... –

Смежные вопросы