2014-12-02 3 views
0

У меня изначально был код вроде ниже, где у меня ничего не было в глобальном пространстве имен, и мне удалось вызвать функции в obj2 из obj1 и наоборот. И все было хорошо.Функция JavaScript, содержащая объекты, которые могут обращаться друг к другу

(function() { 
    var obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      obj2.obj2_f1(); 
     } 
    }; 
    var obj2 = { 
     obj2_f1 : function() { 
      obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 
    $(document).ready(function() { 
     obj1_f1(); 
    }); 
})(); 

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

var com_mycompany_make_sure_unique = new function() { 
    // use 'this.' so that obj1 is not in the global namespace 
    this.obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      com_mycompany_make_sure_unique.obj2.obj2_f2(); 
     } 
    }; 
    this.obj2 = { 
     obj2_f1 : function() { 
      com_mycompany_make_sure_unique.obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 

    $(document).ready(function() { 
     com_mycompany_make_sure_unique.obj1.obj1_f1(); 
    }); 
}; 

, но я не слишком доволен тем, что - Перед вызовом функций через obj1 и obj2 мне нужно добавить все вызовы функций с моим глобальным именем объекта. Я думаю, что мне не хватает трюка.

Спасибо за любую помощь,

Пол

+0

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

+1

Первая функция не будет работать; «готовый» обработчик должен, вероятно, вызывать 'obj1.obj1_f1()', потому что в этой точке нет видимого символа, называемого просто 'obj1_f1'. – Pointy

+0

@Pointy: Ну, символ виден, но его значение 'undefined'. :-) –

ответ

2

Вы можете сделать это (см комментарии):

var com_mycompany_make_sure_unique = function() { 
    // Continue using variables as you were before 
    var obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      obj2.obj2_f2(); 
     } 
    }; 
    var obj2 = { 
     obj2_f1 : function() { 
      obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 

    $(document).ready(function() { 
     obj1.obj1_f1(); 
    }); 

    // Return an object that can be used via the `com_mycompany_make_sure_unique` variable 
    return { 
     obj1: obj1, 
     obj2: obj2 
    }; 
}(); 

Это иногда называют «выявление шаблон модуля», потому что все, что внутри наружной анонимным функция определения области видимости является частной, а затем вы «раскрываете» части, которые вы хотите выявить, помещая их в объект, который вы возвращаете. Если необходимо только выставить obj1, например, и не obj2, вы могли бы сделать это:

return { 
    obj1: obj1 
}; 

Мой вопрос, хотя, почему вам нужно вызывать функции из глобального контекста? С современными обработчиками событий и загрузчиками Asynchronous Module Definition, такими как RequireJS, единственным глобальным, который вам действительно нужен (ugh), является функция (ы) AMD.


Примечание стороны: я заменил ваш var ... = new function() { ... }; с var ... = function() { ... }(); Там нет необходимости использовать new здесь, и это может иметь тенденцию путать людей (и дает результирующий объект дополнительный прототип не нужно). Но вы можете использовать свою оригинальную форму, если хотите, просто измените конец на

this.obj1 = obj1; 
this.obj2 = obj2; 

... а не возвращать объект.

+1

Спасибо. Я знал, что у меня нет трюка! Очень признателен. – user265330

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