2013-09-06 3 views
0

Когда ни один из следующих объектов дочерних не был созданJavascript - TypeOf не работает для динамического объекта

if(typeof this.obj[child1][child2]!=="undefined"){ 
} 

Вышесказанное не работает, однако это делает

if(typeof this.obj[child1]!=="undefined"){ 
} 
+0

Как насчет 'если (TypeOf это .obj [child1]! == "undefined" && typeof this.obj [child1] [child2]! == "undefined") '? –

+0

Ну, если в обоих случаях 'this.obj [child1]' 'undefined', то' this.obj [child1] [child2] 'будет вызывать ошибку, например' не может получить доступ к свойству ... из undefined' –

ответ

1

Вы действительно не нужны typeof ... 'undefined', чтобы определить, является ли this.obj[child1][child2] не undefined. Вместо того, чтобы использовать:

if (this.obj && this.obj[child1] && this.obj[child1][child2]) {} 

Как и в:

var obj = {}; 
obj.c1 = {}; 
alert(obj && obj.c1 && obj.c1.c2 ? 'obj.c1.c2 exists' : 'nope'); 
    //=> "nope" 
obj.c1.c2 = 1; 
alert(obj && obj.c1 && obj.c1.c2 ? 'obj.c1.c2 exists' : 'nope'); 
    //=> "obj.c1.c2 exists" 

Вы можете создать функцию, чтобы определить наличие определенного пути в любом Object:

function pathExists(root,path){ 
    var pathx = path.constructor === Array && path || path.split(/\./) 
    , trial 
    , pathok = true 
    ; 

    while (pathx.length && pathok) { 
    trial = pathx.shift(); 
    pathok = (root = root && root[trial] || false, root); 
    } 
    return pathok; 
} 
// usage examples 
var obj = {c1:1}; 
pathExists(obj,'c1.c2'); //=> false 
pathExists(obj,'c1'); //=> 1 
obj.c1 = { c2: {c3: 3} }; 
pathExists(obj,['c1','c2','c3']); //=> 3 
// your case 
if (pathExists(this,[obj,child1,child2])) { /*...*/ } 
+0

Фу, который работал, спасибо. – user1209203

3

это потому, что приоритет typeof меньше, чем у [] или ., поэтому сначала выполняется [] и выдает ошибку:

> typeof foo == "undefined" 
true 
> typeof foo.bar == "undefined" 
ReferenceError: foo is not defined 

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

function hasKeys(obj, keys) { 
    for(var i = 0; i < keys.length; i++) { 
     if(typeof obj[keys[i]] == "undefined") 
      return false; 
     obj = obj[keys[i]]; 
    } 
    return true; 
} 

if(hasKeys(this, ["obj", "child1", "child2"])) ... 

или лучше, обрабатывать исключение:

try { 
    val = this.obj['foo']['bar']['baz']; 
} catch(err) { 
    // deal with undefined val 
} 
+0

Могу ли я попробовать в выражении if/else? – user1209203

-5

Использование неопределенными вместо «не определено» или попробовать нуль.

+0

'undefined' не является зарезервированным ключевым словом, поэтому проверка' typeof something === "undefined" 'является способом сохранения. И 'undefined' и' null' - это не одно и то же. –

0

использовать это в первом случае -

if(this.obj[child1] && typeof this.obj[child1][child2]!=="undefined"){ 
} 
+0

Возможно, он также должен проверить, является ли 'this.obj [child1]' объектом. –

+0

@RienNeVaPlus, что может 'this.obj [child1]' быть в этом случае, где 'this.obj [child1] [child2]' будет терпеть неудачу? –

+0

Нет, что не требуется. В случае, если 'this.obj [child1]' не является объектом и является литералом, даже тогда javascript автоматически преобразует его в объект, прежде чем проверять элемент 'child2'. – Tushar

-1

Это не работает, потому что он будет бросать ошибку JavaScript. Он будет throw this.obj [child1] не определен. Вы всегда должны проверить, не определено ли это.

if(this.obj[child1] && typeof this.obj[child1][child2]!=="undefined"){ 
} 

EDIT

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

var test = {child1: {child2: "TEST"}}; 
alert(is_defined(test, 'child1', 'child2')); // true 
alert(is_defined(test, 'child1', 'child2', 'child3')); // false 

function is_defined(obj) { 
    if (typeof obj === 'undefined') return false; 

    for (var i = 1, len = arguments.length; i < len; ++i) { 
     if (obj[arguments[i]]) { 
      obj = obj[arguments[i]]; 
     } else if (i == (len - 1) && typeof obj[arguments[i] !== 'undefined']) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    return true; 
} 
+0

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

+0

Это не будет работать, если 'this.obj [child1]' is 'null'. 'TypeError: Невозможно прочитать свойство '...' of null' будет выбрано тогда. –

+0

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

Смежные вопросы