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

JavaScript: Определен ли член?

Мне кажется, что существует четыре разных способа определить, имеет ли данный объект (например, foo) заданное свойство (например, bar):

  • if (foo.hasOwnProperty(bar)) {
  • if ('bar' in foo) {
  • if (typeof foo.bar !== 'undefined') {
  • if (foo.bar === undefined) {

Чтобы определить, есть ли в объекте foo свойство с именем "bar", все три эти выражения эквивалентны? Есть ли какая-либо субъектная семантика, которую я не знаю, что делает любое из этих трех утверждений разными?

4b9b3361

Ответ 1

Нет, они совершенно разные. Пример:

foo = {bar: undefined};
Object.prototype.baz = undefined;
Object.prototype.bing = "hello";

Тогда:

(typeof foo.bar != "undefined")  === false
('bar' in foo)                   === true
(foo.hasOwnProperty('bar'))      === true


(typeof foo.baz != "undefined")  === false
('baz' in foo)                   === true
(foo.hasOwnProperty('baz'))      === false


(typeof foo.bing != "undefined") === true
('bing' in foo)                  === true
(foo.hasOwnProperty('bing'))     === false

Логика-накрест:

  • foo.hasOwnProperty('bar') подразумевает 'bar' in foo
  • typeof foo.bar != "undefined" означает 'bar' in foo
  • Но это единственные выводы, которые вы можете сделать; никакие другие последствия не являются общепринятыми, как показывают вышеприведенные контрпримеры.

Ответ 2

Все они разные:

  • foo.hasOwnProperty('bar') сообщает вам, имеет ли свойство foo и не выполняет поиск по цепочке прототипов.

  • 'bar' in foo проверяет цепочку прототипов и возвращает true, когда находит свойство bar в любом объекте вдоль цепочки.

  • typeof foo.bar != 'undefined' возвращает true, если foo или любой объект по цепочке прототипов имеет свойство bar, а значение не равно undefined.

Вот пример, демонстрирующий эти различия:

var foo1 = { 'bar1': 10, 'bar2': undefined };
function ctor() {}
ctor.prototype = foo1;
var foo2 = new ctor();
foo2.bar3 = 20;

console.log(foo2.hasOwnProperty('bar1')); // false
console.log(foo2.hasOwnProperty('bar2')); // false
console.log(foo2.hasOwnProperty('bar3')); // true
console.log(foo2.hasOwnProperty('bar4')); // false

console.log('bar1' in foo2); // true
console.log('bar2' in foo2); // true
console.log('bar3' in foo2); // true
console.log('bar4' in foo2); // false

console.log(typeof foo2.bar1 != 'undefined'); // true
console.log(typeof foo2.bar2 != 'undefined'); // false
console.log(typeof foo2.bar3 != 'undefined'); // true
console.log(typeof foo2.bar4 != 'undefined'); // false

Ответ 3

одно отличие состоит в том, что метод 1 будет проверять только объект foo для панели свойств, в то время как последние два метода также будут проверять прототип для унаследованного свойства.

Ответ 4

'bar' in foo 

будет выглядеть в любом месте цепи прототипов. Тестирование, чтобы увидеть, если foo.bar! == undefined также вернет true, если bar находится где угодно в цепочке прототипов foo, но помните, если bar определен на foo, а установлен на w90 > , это вернет false.

hasOwnProperty более разборчиво - он вернет true, а bar определяется как прямое свойство foo.

За MDN

Каждый объект, сгенерированный из Object, наследует метод hasOwnProperty. Этот метод может быть использован для определения того, имеет ли объект указанное свойство как прямое свойство этого объекта; в отличие от оператора, этот метод не проверяет прототип объекта цепь.

Ответ 5

Есть действительно некоторые тонкие различия между различными методами/ключевыми словами.

  • foo.hasOwnProperty('bar') возвращает значение true, только если свойство "bar" определено в самом объекте foo. Другие свойства, такие как 'toString', возвращают false, поскольку они определены цепочкой прототипов.

  • Оператор ключевого слова in возвращает true, если указанное свойство находится в указанном объекте. Оба 'bar' in foo и 'toString' in foo вернут true.

  • Поскольку вы проверяете состояние свойства, результат будет истинным, если bar не определен в foo и когда bar определен, но значение установлено на undefined.

Ответ 6

Чтобы добавить к словам других, если вы просто хотите знать, существует ли свойство и имеет значение без ложности (не undefined, null, false, 0, "", NaN и т.д.), вы можете просто сделать это:

if (foo.bar) {
     // code here
}

Пока значения для вас не интересны для ваших конкретных обстоятельств, этот ярлык подскажет вам, была ли переменная настроена на что-то полезное для вас или нет.

Если вы хотите узнать, существует ли свойство на объекте каким-либо образом, я считаю это наиболее полезным, кратким и читаемым:

if ('bar' in foo) {
    // code here
}

Можно также использовать что-то подобное в аргументах функции (опять же, пока значение ложности не является чем-то, о чем вы заботитесь):

function foo(bar) {
    if (bar) {
        // bar was passed and has some non-falsey value
    }
}