2009-03-27 1 views
4

Как вы могли бы сделать в PHP:Как сделать «мягкой», если проверить состояние в Javascript

if (@$some_var_exists) 
    // do stuff 

Как бы вы сделать что-то подобное в Javascript без получаю ошибку?

Благодаря

EDIT: Спасибо за ответы. Тем не менее, проблема, которую я пытаюсь решить, как проверить, если переменная существует, когда он глубоко в объекте, например:

if (someObj.something.foo.bar) 
    // This gives an error in the browser if "someObj.something.foo" is not defined. 

ответ

11

Проверка каждой части цепи:

if (someObj && someObj.something && someObj.something.foo && someObj.something.foo.bar) { 
    // stuff 
} 

Поскольку выражение вычисляется слева направо, и возвращает, как только он находит false, это не приведет к ошибке. Поэтому, если «someObj» существует, но «sometObj.something» этого не делает, он вернет false и никогда не выполнит тест для someObj.something.foo, который бы выбросил ошибку.

+0

Это хорошо, если вы знаете, что someObj был определен первым. –

+0

Разве это не первое, что он проверяет? –

+0

Если someObj не был определен, вы получите сообщение об ошибке для попытки доступа к этой переменной. Если вы предисловите его окном || self scope вы устраняете эту проблему, и по мере того, как вы выполняете поиск, как будто вы второе условие. –

11

Чтобы проверить, является ли переменная определена, вы можете сделать:

if(self.somevar) { 
    ... 
} 

Как отметил Мистер в комментариях, здесь важна часть self.

Или, если вы хотите быть более явным, вы могли бы сделать:

if(typeof somevar != "undefined") { 
    ... 
} 

так, как вы проверяете PHP вар тоже не очень аккуратный или действительно лучшая практика как подавитель @ ошибка дорого и не обязательно в этом случае. Вы можете использовать isset так:

if(isset($some_var_here)) { 
    ... 
} 

EDIT:
Для более конкретной проблемы, я думаю, что @Ryan Watkins ответ способ сделать это, хотя я должен задаться вопросом, почему вы ставите себя в таком положении в любом случае. :)

+0

Я думаю, вы имеете в виду 'typeof somevar! =" Undefined "' - OP, похоже, хочет действовать только в том случае, если существует переменная *. +1 – ojrac

+0

Вот как у меня это. У меня было это как == как секунда. : x –

+0

Первый пример - не очень хорошая практика. Вы всегда должны проверить, была ли переменная когда-либо инициализирована. например: if (self.somevar) ... –

2

Simpler чем ..

if(varname){ 
     ... 
} 

Это относится к переменным, а не объекты.

+0

Это не очень хорошая практика. Вы должны проверить, была ли эта переменная когда-либо инициализирована. if (self.varname) ... или if (typeof varname! = "undefined") –

0

Javascript возвратит ложь в, если заявление, если объект не существует

var myObj = {}; 
if (myObj.someUnknown) 
{ 
    // will not get here if someUnknown doesn't exist. 
} 
+0

Просто аккуратно знать, если вы используете это на некоторых объектах IE, он иногда может выполнять метод, если он существует. –

+0

На самом деле, это интересно, у вас есть ссылка ... – bendewey

+0

Нет, просто знайте, что это работает от IE слишком много лет. Если появится еще один яркий пример, то он пройдет. Еще одним лакомым кусочком будет то, что если у вас есть геттер для свойства, он вызывает их во время этого процесса поиска. –

1

При тестировании на наличие переменной вы никогда не должны слепо проверить это имя переменных. Эти же кольца истинны при поиске свойств и методов глубоко вложенных объектов.

Имея это в виду:

// error will occur if someObj has not ever been defined in your code. 
if (someObj) { 
    // someObj has been defined 
} 

Вы можете обойти это и использовать минимальный код при тестировании против глобального масштаба, который в браузерах это уровень окна.

// safe way to test for global variable. 
if (window.someObj) { 
    // someObj has been defined 
} 

Другой прекрасный тест для глобальной переменной будет с помощью встроенного метода TYPEOF, однако это становится немного утомительно типа, если вам нужно сделать, это достаточно часто.

// another safe method for testing a global variable 
if (typeof someObj != "undefined") { 
    // someObj has been defined 
} 

Теперь для тестирования глубоких вложенных объектов (часто используется в качестве псевдо-пространств имен в JS).

// testing deep nested object 
if (self.someObj && 
    someObj.something && 
    someObj.something.foo && 
    someObj.something.foo.bar) { 
    // do something ... 
} 

всего два окончательных быстрых заметок для продвинутых кодеров:

Иногда в IE, я заметил, что делает этот тип поиска теста/существование фактически называется методом, если я испытывал к нему. например:

// this is an example, I can't recall which actual methods did this off-hand 
if (document.execCommand) { 
    // resultant value of execCommand method gets used to pass/fail the conditional 
} 

И, наконец, очень мягкий побочный эффект такого типа существования поиска в том, что когда у вас есть поглотитель примененного к собственности, она будет реально работать сорбент во время условного тестирования.

// this code only runs in Firefox 2+ 
// and is provided for instructional purposes only 
var foo = { 
    get bar() { alert("bar getter was executed") } 
}; 
if (foo.bar) { 
    // a foo.bar property is defined 
} 
0
function isVarDefined(str) { 
    try { 
     return (typeof eval(str) !== 'undefined'); 
    } 
    catch(e) { 
     return false; 
    } 
} 

Передайте имя переменной в виде строки. Например:

isVarDefined('someObj.something.foo.bar') 

PS: Eval - это зло. Вы должны дезинфицировать значение str, чтобы содержать только имя переменной, а не какой-либо произвольный исполняемый код. Оставленный как упражнение для вас!

1
if (typeof somevar === "undefined") { 
    // then the variable doesn't exist 
3

Следующий должна быть в значительной степени пуленепробиваемым, но хлопоты и работает только тогда, когда вы знаете всю цепочку заранее:

if ('undefined' !== typeof someObj && 
    'undefined' !== typeof someObj.something && 
    'undefined' !== typeof someObj.something.foo && 
    'undefined' !== typeof someObj.something.foo.bar) { 
    // do some stuff 
} 

Вы могли бы быть лучше, чтобы сделать, как следует Четано и использовать TRY/поймать блок вместо:

try { 
    if ('undefined' !== typeof someObj.something.foo.bar) { 
     // do some stuff 
    } 
} 
catch (e) {} 
4

@Scott Evernden и Hedges @ Андрей имеют только полностью правильные ответы до сих пор. Просто делать что-то вроде

if (variable) 

или

if (someObj && someObj.something && ... && someObj.something.foo.bar) 

не является правильным в целом, потому что если someObj.something.foo.bar существует, но равен нулю или ложно, то условие будет ложным. Он будет работать, только если все объекты являются объектами (не номерами, булями или даже строками) и someObj существует.

Единственные правильные способы проверки существования в целом, являются typeof variable !== "undefined", variable !== undefined (если вы знаете, что было объявлено), "property" in variable, или, в зависимости от того, что вы имеете в виду под «существует», object !== null. try/catch также может работать, но это кажется грязным.

Если у вас длинная цепь, нет необходимости проверять каждый шаг для правильного типа/null/undefined/etc.; до тех пор, пока каждое промежуточное значение является объектом (а не числом, строкой или булевым, что имеет дополнительные свойства), они будут оценивать значение true.

if (typeof someObj !== "undefined" && someObj && 
    someObj.something && 
    someObj.something.foo && 
    typeof someObj.something.foo.bar !== "undefined") { 
    // someObj.something.foo.bar exists, but you may need to check for null 
} 
+0

Отличная выноска! Это меня озадачивает, как некоторые из кодов здесь проголосовали и/или просто вклеены вслепую, чтобы люди могли первыми ответить! :) –

+1

Да, это похоже на то, что вместо того, чтобы учиться у людей, которые знают больше, чем они, некоторые люди проголосуют за код, который усиливает их собственные вредные привычки. –

0

Если вам нужно сделать, это много, функция версии, чтобы получить свойство, если оно существует, и возвращать не определено иначе является:

function propertyChain(root, chain) { 
    var properties = chain.split("."); 
    var obj = root; 
    while (properties.length) { 
     if (typeof obj === "undefined" || obj === null) 
      return undefined; 
     obj = obj[properties.shift()]; 
    } 
    return obj; 
} 

так, что:

if (propertyChain(someObj, 'something.foo.bar')) 

является по существу, не метательный вариант (при условии, что вы объявили someObj):

if (someObj.something.foo.bar) 
Смежные вопросы