См. http://jsfiddle.net/FDhQF/1/ для получения тривиального примера.
В чем разница между тем, что не определено, и тем, что не определено в Javascript? Например, попытка получить доступ к свойству для объекта (фактически, попытка доступа к переменной), которая не определена, вернет undefined
. Но вы также можете установить что-нибудь = undefined
. Когда вы это сделаете, попытка получить к нему доступ по-прежнему возвращает undefined, но указатель все еще там. Пример, как и выше, показывает, как итерация по объекту по-прежнему перебирает свойство, которое вы (повторно) объявили как неопределенное. Похоже, есть два разных типа undefined. Может ли кто-нибудь пролить свет на ситуацию?
2 ответа
Оба, доступ к свойству, которое не определено для объекта, и к свойству, содержащему примитивное значение undefined
, вернут вам undefined
.
Например:
var obj = {
a: undefined
};
obj.a; // undefined
obj.b; // undefined
Разница в том, что a
- собственное свойство, а b
- нет:
obj.hasOwnProperty('a'); // true
obj.hasOwnProperty('b'); // false
В первом случае a
является собственным свойством, даже если оно содержит undefined
в качестве своего значения. Во втором случае b
не является собственным свойством, доступ к obj.b
будет искать свойство с именем b
на всем протяжении цепочки прототипов.
Когда цепочка прототипов заканчивается (когда она достигает объекта с null
[[Prototype]]
), поиск свойств заканчивается и undefined
явно возвращается.
Вы должны знать, что метод hasOwnProperty
проверяет только если свойство физически существует в объекте ( собственные свойства), но у нас также есть унаследованные свойства, в этом случае мы можем использовать оператор in
, например:
function Test () {}
Test.prototype.a = 'foo'; // instances of Test will inherit from Test.prototype
var obj = new Test(); // { a="foo", b="bar"}
obj.b = 'bar';
obj.hasOwnProperty('a'); // false
'a' in obj; // true
obj.a; // 'foo'
obj.hasOwnProperty('b'); // true
Как видите, obj
наследуется от Test.prototype
, а свойство a
не является собственным свойством , но доступно через цепочку прототипов. Вот почему hasOwnProperty
возвращает false
, а оператор in
возвращает true
.
Вы можете увидеть, как разрешаются внутренние свойства с помощью [[Get]]
а> внутренняя операция
Примечания:
- Доступ к
undefined
в качестве идентификатора не считается безопасным в ECMAScript 3 (наиболее широко применяемой версии языкового стандарта), потому что вместо ключевого слова языка (например,null
) просто свойство глобального объекта, и оно доступно для записи в этой версии спецификации, что означает, что если кто-то заменит его значение (например,window.undefined = 'LOL';
), это нарушит ваш код.
Оператор typeof
, как упоминает @strager, может быть вместо этого используется, например:
if (typeof obj.prop == 'undefined') { /*....*/ }
Этот оператор всегда возвращает строку (можно использовать ==
:), и его значение зависит от типа его операнда, возможные значения описаны здесь.
Другой распространенный способ решить эту проблему - объявить вашу собственную переменную undefined
, доступную в области действия ваших функций, например, некоторые библиотеки используют следующий шаблон:
(function(undefined) {
// code here
})();
У функции есть аргумент с именем undefined
, и он выполняется немедленно, не передавая ему никакого значения (последняя пара или скобки выполняют вызов).
Возможно, стоит упомянуть, что undefined
глобальное свойство наконец-то описан в ECMAScript 5 как недоступный для записи (неизменяемый, а также неперечисляемый и не настраиваемый -non deletable-).
Использование метода
hasOwnProperty
непосредственно из экземпляра объекта также не считается безопасным , потому что, если у некоторого объекта есть свойство с таким же именем, исходный метод будет затенен. Например:var obj = { hasOwnProperty: function () { /* evil code :) */ } };
Если вы позвоните:
obj.hasOwnProperty('prop');
Будет выполнен метод, определенный для объекта (и вы не захотите этого, поскольку вы точно знаете, какой метод вы хотите вызвать ...), потому что он затеняет метод из {{X0} }, однако его можно безопасно вызвать:
Object.prototype.hasOwnProperty.call(obj, 'prop');
Здесь хорошее объяснение "undefined ". Суть, однако, в том, что установка чего-либо на «undefined» не является его определением в UN, потому что «undefined» на самом деле является примитивным значением, которое используется, когда переменной (или свойству) не было присвоено значение.
Похожие вопросы
Связанные вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.