2012-03-24 3 views
4

Я часто использовал следующий шаблон в моем Javascript:Javascript Неопределенное Строка собственности Truthiness

x = couldBeNullThing || valueIfItIsNull; 

, потому что он бьет, чем:

x = couldBeNullThing ? couldBeNullThing : valueIfItIsNull; 

Я также часто используют небольшой вариант того же шаблона :

x = x || valueIfXIsNotDefined; 

Это все замечательно ... кроме проблемы, я недавно обнаружил:

foo = ""; 
//assert foo.x === undefined; 
foo.x = foo.x || valueIfXIsNotDefined; 
//assert foo.x === undefined; 

Другими словами, если у вас есть строка, и вы выполняете string.aPropertyThatStringDoesntHave || foo, вы не получите ни foo, ни фактическое значение; вместо этого вы становитесь неопределенными.

Может ли кто-нибудь объяснить, почему это так? Мне кажется, что если foo.x не определено, то foo.x || anythingElse всегда должен приводить к чему-либоElse ... так почему же это не так?

+0

Интересно, что это работает, если вы делаете 'foo = new String (" ")' – Gohn67

+0

Еще одна вещь, которую я заметил, заключается в том, что использование 'console.log (foo)' возвращает (пустая строка) "и когда используя новый String (""), он возвращает объект String. Кроме того, я нахожусь в Firefox. Может отличаться в других браузерах. – Gohn67

+0

Уг извините за спам. Но это интересный вопрос. Также 'foo = String (" ")' возвращает "(пустая строка). Кроме того, что-то вроде 'foo =" Test ".substr (1)' возвращает только строковое значение, а не объект. – Gohn67

ответ

2

В то время как я знаком с концепцией assert Я не знал, что JavaScript имеет эту функциональность. Так с этим в виду, я мог бы совершенно неправильно, но мне кажется, что это утверждение:

assert (foo.x || valueIfXIsNotDefined) === undefined; 

... вызывает функцию с именем assert(), передавая ему параметр foo.x || valueIfXIsNotDefined, а затем сравнивая возвращаемое значение из assert() с undefined. Возможно, что вам нужно это:

assert(foo.x || valueIfXIsNotDefined === undefined); 

Если я пытаюсь что-то подобное с console.log():

var foo = "", 
    valueIfXIsNotDefined = "test"; 
console.log(foo.x === undefined); 
console.log(foo.x || valueIfXIsNotDefined === undefined); 

Затем он регистрирует:

true 
false 

Точно так же, после того, как:

var result = foo.x || valueIfXIsNotDefined; 

result является "test".

http://jsfiddle.net/YBPyw/

Кроме того, если вы на самом деле пытаются присвоить foo.x равное к чему-то (где foo была строка) она не работает, поэтому, когда вы позже тест foo.x это даст undefined.

+0

Извините, вы правы, что JS не имеет встроенного assert. Я просто пытался объяснить ситуацию, но я действительно должен был сказать «// assert ..», чтобы быть более ясным (я отредактирую вопрос). Ваше последнее предложение ответило на мой вопрос (спасибо), но для его понимания потребовались комментарии от Gohn67. Для других читателей, как я понимаю, причина var foo = ""; foo.x = 1; foo.x! = 1; потому что во втором утверждении foo временно преобразуется в новую String (foo). Это позволяет ему получить назначенное ему свойство x, но затем оно возвращается к тому, чтобы быть примитивным (недействительным). – machineghost