2011-01-11 3 views
2

Скажем у меня есть эта функция, которая динамически создает свое пространство имен для меня, когда я просто передать ему строку, (я уверен, что в основном то, что библиотека YUI JS делает):Как вы можете программно добавить функцию в вложенное пространство имен?

MyObj.namespace('fn.method.name'); 

приведет к

MyObj.fn.method.name = {} 

создается - все три уровня эквивалентны пустому объекту.

Теперь, что я хочу сделать, это сделать последний уровень, в данном случае name, установленный в функцию, но без необходимости повторного создания вновь созданного объекта.
Так вместо того, чтобы сделать это:

function fnName() { /* some code here */ } 
MyObj.namespace('fn.method.name'); 
MyObj.fn.method.name = new fnName(); 

я хочу назвать что-то вроде:

MyObj.add('fn.method.name', fnName); 

и внутренне, метод add бы программно экземпляр переданному в функции:

MyObj.fn.method.name = new fnName() 

В способе, которым я его реализовал, я могу создать объект пространства имен и установить его на пустой объект, однако, когда я пытаюсь создать экземпляр переданной функции и связать это пространство имен с переданной функцией, она никогда не добавляется в пространство имен. Вместо этого всегда возвращается пустой объект. Есть идеи?

Редактировать: Вот namespace метод. это прикреплено к базовому объекту как объект JSON, поэтому, пожалуйста, игнорировать форматирование:

namespace: function (ns) { 
    var _ns = ns.split('.'), 
     i = 0, nsLen = _ns.length, 
     root = this; 
    if (_ns[0] === gNS) { 
     _ns.shift(); 
      nsLen = _ns.length; 
     } 
     for (i = 0; i < nsLen; i++) { 
      // create a property if it doesn't exist 
      var newNs = _ns[i]; 
      if (typeof root[newNs] === "undefined") { 
       root[newNs] = {}; 
      } 
      root = root[newNs]; 
     } 
     return root; 
    } 

edit2 - Убрана прошел в fn аргумент

+0

Где вы получили функцию пространства имен() из? –

+1

Вы противоречите себе. Сначала вы говорите, что хотите установить 'имя' в функцию, но затем вы говорите, что хотите установить его в результат' new fnName() '. –

+1

Очевидно, что «все три уровня» не могут быть пустыми объектами: объект fn содержит свойство метода, а объект метода содержит свойство name. –

ответ

1

Были ли вы ищете что-то вроде этого:

var root = {}; 

function create(ns, fn) { 
    var nsArray = ns.split(/\./); 
    var currentNode = root; 

    while(nsArray.length > 1) { 
     var newNS = nsArray.shift(); 

     if(typeof currentNode[newNS] === "undefined") { 
     currentNode[newNS] = {}; 
     } 

     currentNode = currentNode[newNS]; 
    } 

    if(fn) { 
     currentNode[nsArray.shift()] = fn; 
    } 

    else { 
     currentNode[nsArray.shift()] = {}; 
    } 
} 

Тогда:

create("a.b.c"); 

console.log(root.a); 
console.log(root.a.b); 
console.log(root.a.b.c); 

Дает:

Object { b={...}} 
Object { c={...}} 
Object {} 

И:

create("d.e.f", function() { console.log("o hai"); }); 

console.log(root.d); 
console.log(root.d.e); 
console.log(root.d.e.f); 

Дает:

Object { e={...}} 
Object {} 
function() 

Вызов функции вы определили:

root.d.e.f(); 

Выдает:

o hai 
+0

спасибо, Вивинь. должен был изменить мой сценарий, чтобы заставить его работать, но, похоже, отлично работает! – hellatan

+0

@dtan Нет проблем, рад помочь! Я написал это довольно быстро. Но вы должны иметь возможность заставить его работать аналогичным образом, если вы установите 'currentNode'' this'. –

+0

yup, именно то, что я сделал вместо этого, спасибо – hellatan

0

Ну вы не дали функции имен но ваш добавление функции может выглядеть примерно так:

MyObj.add = function (namespace, value) { 

    var names = namespace.split('.'), current = this, name; 

    while (names.length > 1) { 

     name = names.shift(); 
     current[name] = {}; 
     current = current[name]; 

    } 

    current[names[0]] = value; 

}; 

Этот код присваивает значение, указанное последней части пространства имен. Вы можете изменить его на current[names[0] = new value();, если хотите объект, построенный переданной функцией (и вы предполагаете, что функция конструктора не принимает никаких аргументов).

+0

Я думаю, что это сработает, david, но Vivin's проверит, существует ли объект уже. – hellatan

0
function ns() { 
    var root = window; 

    for (var i = 0; i < arguments.length; i++) { 
     var arr = arguments[i].split(/\./); 

     for (var j = 0; j < arr.length; j++) { 
      var item = arr[j]; 

      if (typeof item !== 'string') { 
       root = item; 
      } 
      else { 
       if (!root[item]) { 
        root[item] = {}; 
       } 
       root = root[item]; 
      } 
     } 
     root = window; 
    } 
} 

, то вы можете создать с помощью

ns('fn.method.name'); 

или

ns('fn.method.name','fn.method.secondName'); 

и вызова с использованием

fn.method.name 

Эта функция создает пространство имен на 'окно', так же вы можете использовать

window.fn.method.name 
+1

Единственная проблема заключается в том, что вы явно создаете новое пространство имен объектным литералом и не можете присоединить что-либо еще (то есть функции), как вы можете видеть в ответе, который я выбрал выше , – hellatan

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