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
Верно, если я ошибаюсь
Ответы
Ответ 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, если это не так. Этот метод не проверяет, свойство существует в цепочке прототипов объекта; собственность должна быть членом самого объекта.