Подтвердить что ты не робот

HasOwnProperty vs 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

Верно, если я ошибаюсь

4b9b3361

Ответ 1

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

Вы можете использовать "defineProperty" для определения свойств, которые не перечислены; см. эту ссылку в MDN.

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

Что нравится:

obj.hideMe = null;

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

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

Ответ 2

hasOwnProperty вернет true даже для неперечислимых "собственных" свойств (например, length в Array), propertyIsEnumerable вернет true только для перечислимых "собственных" свойств. (Свойство "перечисляемое" является свойством, которое отображается в for..in циклах и т.д.)

Пример:

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>

Ответ 3

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

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

и

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

demo: http://jsfiddle.net/aby3k/

Ответ 4

Разница в том, что свойствоIsEnumerable возвращает true только в том случае, если свойство существует и если возможно использовать ForIn для свойства, hasOwnProperty вернет true, если свойство существует независимо от поддержки ForIn

Из MSDN:

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

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