2015-11-01 3 views
3

Я пытаюсь лучше понять пространство имен в javascript и нашел пример javascript Немедленно вызывается выражение функции, которое принимает объект окна в качестве параметра. Вот код из него:Передача объекта window в пространство имен Javascript

var CG = CG || {}; 
CG.main = (function(window) { 
    var FOCAL_LENGTH = 8.0; 
    var context, width, height, startTime; 

    var init = function() { 
     var element = document.getElementById("canvas1"); 
     context = element.getContext("2d"); 

     width = element.width; 
     height = element.height; 

     startTime = (new Date()).getTime()/1000.0; 
     tick(); 
    } 

var original_onload = window.onload || function() {}; 
    window.onload = function() { 
     original_onload(); 
     CG.main.init(); 
    } 
    return { 
     init: init, 
     draw: draw_shape, 
     clear: clear_canvas 
    }; 
}(window)); 

В конце определения пространства имен, есть строка с окном в скобках, которые я запутался, функциональность. Я думаю, что цель добавления параметра окна в конец определения - связать глобальную переменную окна с пространством имен, которое затем добавит в окно разные свойства, но я не могу быть уверен.

В другом примере есть случайное имя переменной передается в определение пространства имен, и в конце определения пространства имен, фактическое имя пространства имен передается в качестве параметра:

var namespace = namespace || {}; 
// here a namespace object is passed as a function 
// parameter, where we assign public methods and 
// properties to it 
(function(o){ 
    o.foo = "foo"; 
    o.bar = function(){ 
     return "bar"; 
    }; 
})(namespace); 
console.log(namespace); 

Так здесь есть несколько вопросов:

  1. Что такое функция передачи параметра в конце определения пространства имен?

  2. Если моя интуиция относительно того, как все это работает неправильно, какова общая структура для создания такого пространства имен javascript?

Очевидно, что я очень новичок в этом, поэтому любая помощь будет оценена, спасибо.

+2

Это просто объект передается в качестве параметра функции. В этом нет ничего особенного. – SLaks

+0

С вашим вторым примером кода перепишите его как функцию, с которой вы привыкли, вместо _IIFE_. Что теперь означает скобка? –

ответ

4

Я попытаюсь объяснить это, а также могу, но мое понимание этого происходит от Кайла Симпсона. Он классный, ты должен посмотреть на него. :-D

Вы задаете вопрос о вызываемых функциональных выражениях (IIFE), передавая им аргументы и почему кто-то это сделает.

Во-первых, причина, по которой IIFE используются в этом контексте, заключается в ограничении объема переменных.

Это важно, потому что по мере того, как программы становятся больше и много частей добавляются, вы можете легко иметь конфликты от одной переменной к другой.

app.js может иметь

variable = "thing"; 

и вскоре после того, как somethingelse.js может иметь

variable = "not thing"; 

Это огромная проблема. Его избегают в javascript, создавая «модули» или функции, которые сразу запускаются и запускаются один раз.

Таким образом, переменные и методы, которые вы создаете в своей функции, не «загрязняют глобальную область/пространство имен».

НО, что, если вам НУЖНО или ХОТЕЛ, что-то, что будет доступно на глобальном объекте окна?

Ну, вы можете сделать это, добавив его в «окно», которое является глобальной областью в javascript.

(function Module(window){ 
    var _thing = "private thing that only exists in this function"; 
    window.thing = _thing; 
     //IS NOW AVAILABLE GLOBALLY AND EXPLICITLY ON WINDOW OBJECT 
     //window.onload you can wait for DOM/page before running the rest 
})(window); 

Вы также могли бы назвал это все, что вы хотели внутри вашей функции:

(function niftyModule(global){ 

    global.variable = "nifty text!"; 

})(window) 

Это становится особенно важным, когда вы используете несколько библиотек.

По какой-то причине всем нравится использовать «$» в качестве представления своей библиотеки, чтобы вы могли получить доступ к их приватным методам (которые на самом деле являются просто функциями внутри IIFE тоже! (Это действительно популярный способ создания хороших вещей) .

Так что, если вы используете JQuery и 2 других библиотек, которые также использовать $ для доступа к их общедоступные методы/API ??

Easy, вы можете назначить, какой вы хотите назначить какую переменную внутри функции/модуль, передав его в качестве аргумента!

(function NiftyModule(window, $){ 

//Now, every time you use $ in here it means jQuery and not something else! 

})(window, jQuery); 

Важно играть с функциями и возможностями. Постройте несколько переменных по-разному.

К примеру, ....

var text = "nifty text"; 

же, как

text = "nifty text"; 

Как насчет, если вы делаете то же самое внутри функции? Как эти две версии отличаются?

Кроме того, привыкнуть к созданию собственных программ в IIFE и правильному ограничению объема кода, который вы пишете.

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

Сложно сначала, но в будущем это избавит вас от многих проблем и ошибок!

Наконец, в вашем примере:

//initialize a global variable called namespace. If this already 
//existed then assign it the previous values. If not, make it an empty 
//object. 
var namespace = namespace || {}; 

//pass namespace into an IIFE. Within the IIFE refer to namespace as "o" 
(function(o){ 
    //assign a variable to namespace 
    o.foo = "foo"; 

    //assign a method to namespace 
    o.bar = function(){ 
     return "bar"; 
}; 
})(namespace); 

//now when you log namespace it will have those properties. 
console.log(namespace); 
+1

Во-первых, спасибо за ответ! Это было действительно ясно и лаконично и прямо обращено к тому, что я просил! У меня только вопрос. Я также узнал, что пространство имен также может быть выполнено с использованием объектов литерала функции из [this] (http://addyosmani.com/blog/essential-js-namespacing/#beginners) ссылки, есть ли у вас какие-либо рекомендации о том, когда использовать каждый метод ? – loremIpsum1771

+1

На данный момент вы всегда должны использовать метод в ссылке. Возврат объекта (который создает открытый API). Пока вы не будете довольны областью действия, избегайте окна вместе и заставляйте себя понимать, что происходит. –

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