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 - нет - так что есть разница в том, как они представлены внутри (по крайней мере, в Chrome).

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
40
0
27 625
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

"содержит" ? Это не ECMAScript. Даже если бы это было так, ваше решение замедляет работу и использует больше ресурсов, чем необходимо. Используйте «x in y», как сказано в других ответах.

some 22.12.2008 19:07

Я знаю, я забыл, что в ECMAScript был оператор «in» = P.

Claudiu 22.12.2008 22:41

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

Нет, он определяет это с помощью примитивного значения undefined.

some 22.12.2008 14:18

Чтобы не определить его, нужно использовать «удалить».

Tomalak 22.12.2008 14:27

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

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

или же..

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

они будут действовать одинаково для обоих вариантов, я думаю

Claudiu 22.12.2008 13:47

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

Установка его на примитивное значение undefined не удаляет свойство, но вы теряете ссылку на то, что свойство содержит. Это не имеет ничего общего с неработающей сборкой мусора.

some 22.12.2008 14:20
Ответ принят как подходящий

Немного более простой способ, чем ваш метод, - использовать Javascript в операторе

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

Входит ли ключевое слово in в стандарт ECMAScript? Он реализован в Gecko и Webkit, но я не знаю, всегда ли можно полагаться на его присутствие.

kpozin 14.01.2011 23:43

@kpozin Можно смело использовать in. См. Этот вопрос: stackoverflow.com/questions/2920765/…

chiborg 13.03.2012 14:11

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

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

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

Ах, одна там нить антипаттернов.

undefined - это не ключевое слово.

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

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

ах, очень интересно. одно примечание, однако - установка значения "UnDeFiNed" вызовет ошибку времени компиляции, поскольку эта переменная не определена. установка его на "Object.randomStringinserthereplease" действует так, как вы говорите.

Claudiu 22.12.2008 14:30

вы имеете в виду время выполнения, а не компиляцию с JS - но вы правы, мое описание предполагает объем. Проблема возникает из-за того, что undefined можно рассматривать как константу во многих ситуациях и поддерживается некоторыми браузерами, но это нет константа, и это небезопасно.

annakata 22.12.2008 14:47

Если вы хотите знать, является ли что-то неопределенным независимо от того, кто-то изменил значение undefined: typeof x === "undefined"

some 22.12.2008 19:14

@annakata: undefined - примитивное значение, см. раздел 4.3.9 спецификации ECMAScript. Вы ошибаетесь, когда говорите: «вы присваиваете ему значение символа undefined, который вы не определили» (продолжение)

some 22.12.2008 19:57

@annakata: Однако вы правы в том, что это не константа, и что она будет давать неожиданное поведение, если undefined определено для чего-то другого. Так будет это: eval = function () {alert ("eval больше не поддерживается");}

some 22.12.2008 19:59

^^ не нанимайте разработчиков, которые написали бы "var undefined = true" в своем javascript.

Josh Mc 17.02.2015 05:00

Другие вопросы по теме