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

JavaScript. Определите, определено ли свойство и установлено значение "undefined" или undefined

Скажем, у меня есть следующий код:

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 in o) цикла даст "x" в качестве одной из строк, а при выполнении этого в t не будет - поэтому существует разница в том, как они представлены внутри (по крайней мере, в Хром).

4b9b3361

Ответ 1

Несколько проще, чем ваш метод, использовать Javascript в операторе

alert('x' in o); // true
alert('x' in t); // false

Ответ 2

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 НЕ удаляет его.

Правильный способ сделать это - использовать в, например roborg.

Обновление: undefined - это примитивное значение, см. Спецификация языка ECMAScript, раздел 4.3.2 и 4.3.9.

Ответ 3

Ach, один для потока анти-шаблонов.

undefined не является ключевым словом.

Когда вы назначаете write var foo = undefined;, вы присваиваете ему значение символа undefined, которое вы не определили, и, следовательно, значение, которое вы получите, это "undefined". Вы получите точно такой же результат, если бы назначили ему undefined или NotFineAtAll или _qwertyuiop

Почему это так ужасно? Ну, кроме того, что это приводит к ложному пониманию происходящего, что произойдет, если вы загрузите библиотеку или наняли разработчика, который пишет var undefined = true;

Ответ 4

Что-то вроде этого?

function isDefined(var){
   return (typeof(window[var]) == 'undefined') ? false : true;
}

или..

function isDefined(var){
   return (window.var === undefined) ? false : true;
}

Ответ 5

Нет. Я не думаю, что переменная, равная 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

Ответ 6

Один из способов сделать это:

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'. Это единственный способ?

Ответ 7

Вы можете попробовать поставить часы на One.x, но это сообщит вам только в то время, когда он получит undefined.