Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Needs to understand Backbone main function

I'm trying to learn advance JavaScript and some people suggested to learn from Backbone.js source code

(function(factory) {

   //There are some lines of code here...

})(function(root, Backbone, _, $) {

   //Many lines of code here 

});
  • Is the factory in (function(factory), the root that is in (function(root, Backbone, _, $)?
  • What is factory?
  • What is Backbone?
  • What is _?
  • What is $?
like image 232
Lash Doni Avatar asked Feb 07 '23 04:02

Lash Doni


2 Answers

You are looking at the AMD module pattern, which I wouldn't spend too much time focusing on. factory is the function with "Many lines of code". The first function you encounter calls factory after it loads Backbone's dependencies - underscore.js (_) and jquery.js ($). Think of it as a dependency-injection version of:

<script src="jquery.js"></script>
<script src="underscore.js"></script>
<script>
function Backbone() {
  // do stuff that depends on underscore and jquery
}
</script>

Is the factory in (function(factory), the root that is in (function(root, Backbone, _, $)?

No, answered above

What is factory?

The guts of the Backbone library which is initialized once its dependencies are loaded

What is Backbone?

An empty object to start out with root.Backbone = factory(root, exports, _, $); where exports is initialized to {} for a given module

What is _?

The underscore.js library

What is $?

The jquery library

like image 154
Rob M. Avatar answered Feb 08 '23 16:02

Rob M.


Let’s make it a bit easier by naming the anonymous functions.

(function definingFn(factory) {

   //There are some lines of code here...

})(function factoryFn(root, Backbone, _, $) {

   //Many lines of code here 

});

It could also be written like this:

function definingFn(factory) {/* code here */}
function factoryFn(root, Backbone, _, $) {/* code here */}
definingFn(factoryFn);

So, definingFn receives factoryFn as named argument factory. So factory is factoryFn, the function you pass to the first function as argument.

Then inside of the definingFn, other variables you are asking about are being defined:

(function(factory) {

  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
  // We use `self` instead of `window` for `WebWorker` support.
  var root = (typeof self == 'object' && self.self === self && self) ||
            (typeof global == 'object' && global.global === global && global);

  // Set up Backbone appropriately for the environment. Start with AMD.
  if (typeof define === 'function' && define.amd) {
    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
      // Export global even in AMD case in case this script is loaded with
      // others that may still expect a global Backbone.
      root.Backbone = factory(root, exports, _, $);
    });

  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
  } else if (typeof exports !== 'undefined') {
    var _ = require('underscore'), $;
    try { $ = require('jquery'); } catch (e) {}
    factory(root, exports, _, $);

  // Finally, as a browser global.
  } else {
    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
  }

})(function(root, Backbone, _, $) {
  // more code here
})

There are several conditions that detect the environment of this script and each invoke the factory function with certain value.

Let’s review just the "browser" environment:

First line in definingFn defines the root, the global object. The library is using self global object (read about it on MDN) in case of browser environment.

Then empty object is supplied as in place of Backbone named argument, to use as a "namespace" to attach things defined in factoryFn.

Then global variable for underscore library, which uses _ as its name is passed.

Then there’s $ object, which can be jQuery, Zepto or Ender, one of these libs, which Backbone is using for event delegation and XHR.

like image 30
Misha Reyzlin Avatar answered Feb 08 '23 17:02

Misha Reyzlin