JavaScript - Определяет, определено ли свойство и установлено ли для него значение 'undefined' или undefined
-
23-08-2019 - |
Вопрос
Допустим, у меня есть следующий код:
function One() {}
One.prototype.x = undefined;
function Two() {}
var o = new One();
var t = new Two();
o.x
и t.x
будут ли оба оценивать, чтобы undefined
. o.hasOwnProperty('x')
и t.hasOwnProperty('x')
оба вернут false;то же самое относится и к propertyIsEnumerable
.Два вопроса:
- Есть ли какой-либо способ определить, что o.x определен и установлен в
undefined
? - Есть ли когда-нибудь для этого какая-нибудь причина?(должны ли эти два понятия быть семантически эквивалентны?)
Небольшое предостережение:выполнение цикла (для propName в o) приведет к получению 'x' в качестве одной из строк, в то время как выполнение этого в t не приведет - так что есть разница в том, как они представлены внутренне (по крайней мере, в Chrome).
Решение
Немного более простой способ, чем ваш метод, заключается в использовании Javascript в операторе
alert('x' in o); // true
alert('x' in t); // false
Другие советы
object.hasOwnProperty(name) возвращает true только для объектов, которые находятся в одном объекте, и false для всего остального, включая свойства в прототипе.
function x() {
this.another=undefined;
};
x.prototype.something=1;
x.prototype.nothing=undefined;
y = new x;
y.hasOwnProperty("something"); //false
y.hasOwnProperty("nothing"); //false
y.hasOwnProperty("another"); //true
"someting" in y; //true
"another" in y; //true
Кроме того, единственный способ удалить свойство - это использовать delete .Установив для него значение undefined, НЕ удаляйте его.
Правильный способ сделать это - использовать в Нравится роборг сказал.
Обновить:неопределенный является примитивным значением, см. Спецификация языка ECMAScript разделы 4.3.2 и 4.3.9.
Ach, один для потока anti-patterns там.
undefined
это не ключевое слово.
Когда вы назначаете запись var foo = undefined;
вы присваиваете ему значение символа undefined
который вы не определили, и, следовательно, значение, которое вы получите, равно "undefined"
.Вы бы получили точно такой же результат, если бы назначили его UnDeFiNeD
или NotFineAtAll
или _qwertyuiop
Почему это так ужасно?Ну, помимо того факта, что это приводит к ложному пониманию происходящего, что произойдет, если вы случайно загрузите библиотеку или наймете разработчика, который пишет var undefined = true;
Что-то вроде этого?
function isDefined(var){
return (typeof(window[var]) == 'undefined') ? false : true;
}
или..
function isDefined(var){
return (window.var === undefined) ? false : true;
}
Нет.Я не думаю, что переменная, равная undefined
должно быть признано "определенным".
Устанавливаем его равным undefined
напрямую - это просто ленивый способ его удаления - в сочетании с использованием delete
ключевое слово.Я полагаю, это просто означает, что сборка мусора не повлияла на переменную / свойство.
[Редактировать]
Что касается вашего комментария по поводу hasOwnProperty
и propertyIsEnumerable
, методы / свойства прототипа не являются ни собственными, ни перечислимыми объектом.
Object.prototype.foo = 'something';
var o = {bar: 'anything'};
o.hasOwnProperty('foo'); //=> false
o.hasOwnProperty('bar'); //=> true
Object.prototype.hasOwnProperty('foo'); //=> true
Один из способов сделать это заключается в следующем:
var definedProperties = [];
for (var prop in o) definedProperties.push(prop);
if (o.x === undefined && contains(prop, 'x')) {
//x is defined, but set to undefined
}
где contains
просто проверяет, является ли какой-либо элемент в массиве 'x'
.Неужели это единственный способ?
Вы могли бы попробовать установить часы на One.x, но это сообщит вам об этом только в тот момент, когда оно станет неопределенным.