开发者

Difference Between Javascript Wrapping Methods

It is generally accepted that Javascript code should be wrapped in a function to prevent leaking to the global scope and just assign whatever you need outside of each function to the head object (window in web browsers).

I've seen two primary methods of this in the wild:

Method 1:

(function() {
  // code here
}).call(this);

Method 2:

(function() {
  // code here
})();

Method 1 is from compiled CoffeeScript code, and Method 2 seem开发者_如何学Pythons to be the preferred style for jQuery plugins:

Modified Method 2 for jQuery:

(function($) {
  // JQuery Code
})(jQuery);

Question: What is the difference between Method 1 and Method 2? CoffeeScript likes to focus on conciseness, so I figure there must have been a reason for the people behind CoffeeScript to choose Method 2 over Method 1.


They are very different.

Method 1 using call, allows you the change what this is inside the function. For example:

(function() {
    alert(this); // DOMWindow
}).call(window);


var myObj = {a: 0};
(function() {
    alert(this); // Object => myObj {a: 0}
}).call(myObj);

Be careful though as you can still dump stuff on the global scope with both approaches:

(function () {
    a = 5; // global
    var p = 10; // private to this function
})();


The difference between method one and two depends on the context they are used in.

As in method one, executing a function with call will use the first argument as the 'this' within the function. In method two, 'this' within the function will refer to the global object because 'this' has not been set by the call (except in ES 5 strict mode where it will be undefined).

With that knowledge in your head, try to think about what would happen if both of those functions were places in the root of a JS file to be loaded in a browser.

In that context, the 'this' being passed to 'call' in method one would refer to the window object, which is the global object in a browser. Method two will accomplish the same thing because functions where 'this' is not set by the call have their this set to the global object (except in ES5 strict mode as noted above).

So for this situation, they would behave the same.

However, there are situations where that is not the case.

var obj = {
  f: function() {
    (function() {
      // 'this' here is 'obj' if called as obj.f()
    }).call(this);

    (function() {
      // 'this' not set by the call, defaults to 'window' (ES5 caveat)
    })();
  }
};

obj.f();

Method one is cleaner because it explicitly passes through the value of the outer 'this', reducing the chance of confusion, and adds flexibility.

Method two is shorter and easier if 'this' doesn't matter.

The jQuery version is used as an easy way to always be able to access jQuery via the '$' variable, while still allowing code outside of jQuery to have $ mean something else.


Most of the time there is no difference. Method 1 explicitly sets what the value of 'this' will be inside of the immediately executed function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜