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

Более удобный способ проверки пространства имен JavaScript

Теперь у меня есть модуль, который следует за длинной цепочкой пространств имен, например:

TOP.middle.realModuleName = function () { /*...*/ }

Мне нужно использовать этот модуль на странице, и я не уверен, включила ли эта страница пространство имен Top.middle. Поэтому я должен был бы сделать что-то вроде:

if (typeof TOP !== 'undefined' && TOP.middle && TOP.middle.realdModuleName) {
    new TOP.middle.realModuleName();
}

Я думаю, что инструкция if выглядит очень длинной и многословной. У кого-нибудь есть предложения по написанию более удобного шаблона проверки параметров для этого случая?

4b9b3361

Ответ 1

просто инкапсулировать его в TRY/CATCH?

try {
    return new TOP.middle.blablabla();
}
catch(err) {
    // oh no!
}

return null;

Ответ 2

Попробуйте эту простую вспомогательную функцию:

function exists(namespace) {    
   var tokens = namespace.split('.');
   return tokens.reduce(function(prev, curr) {
      return (typeof prev == "undefined") ? prev : prev[curr];
   }, window);
}

Он принимает вход String и возвращает объект, если он существует. Вы можете использовать его следующим образом:

var module = exists("TOP.middle.realModuleName");

Например:

exists("noexist"); // returns undefined
exists("window"); // returns DOMWindow
exists("window.innerHeight"); // returns Number
exists("window.innerHeight.toString"); // returns Function
exists("window.innerHeight.noexist"); // returns undefined

Он также корректно работает для выражений, которые вычисляются как false:

testNum = 0;
testBool = false;
testNull = null;

exists("testNum"); // returns 0
exists("testBool"); // returns false
exists("testNull"); // returns null

Ответ 3

Я бы попробовал что-то вроде этого, хотя он подвержен ошибкам, если получает некоторый фанковый ввод:

if(check("TOP.middle.realModuleName")) {
  //exists
}

//namespace checking function
function check(ns) {

  var pieces = ns.split('.'),
      current = window;

  for(i in pieces) {    
    if(!(current = current[pieces[i]])) {
      return false;
    }
  }

  return true;
}

Ответ 4

Вы можете использовать try/catch и искать 'not_defined':

try {
    TOP.middle.realModuleName = function () { /*...*/ };
} catch(e) {
    if ( e.type == 'not_defined' ) {
        // exception
    }
    else {
        // throw other errors
        throw e;
    }
}

Ответ 5

Вы можете сделать все это в одной строке таким образом:

TOP && TOP.middle && TOP.middle.realdModuleName && new TOP.middle.realdModuleName;

Обратите внимание, что ваша функция будет запущена немедленно. Если вы хотите сохранить функцию для последующего повторного использования, просто назначьте ее (var module =). Если функция модуля не определена, то undefined устанавливается/выбрано.

Ответ 6

Я использую функцию, которая анализирует пространство имен и создает его, если он не существует. Вот функция:

framework.namespace = function(baseName){
  var ns = baseName.split('.');
  var o = window;
  for (var i=0, l=ns.length; i < l; i++){
    o = o[ns[i]] = o[ns[i]] || {};
  }
  return o;
};

Затем, прежде чем мне нужно использовать пространство имен, я делаю это:

framework.namespace("TOP.middle.realModuleName");
TOP.middle.realModuleName = function(){...};