开发者

Anonymous Member Pattern Export/Import Function

I'm a bit confused. What is the purpose of the parameters when you initiate an anonymous member pattern开发者_StackOverflow中文版 designated below:

(function (<ParameterA>) {

})(<ParameterB>);
  1. I understand that Parameter A is used to designate the scope of the function is this true?
  2. Is ParameterB where you export the function?

Finally, I often see script indicating the following:

})(jQuery || myfunc);

Does that mean they're exporting these or returning these objects? And what's the point of using the two pipes (||); It a field goal thing?

Thanks in advance. Looking forward to interesting discussion.


Parameter A does not designate the scope of the function. The function's position determines the scope of the function. ParameterB is not where you export the function. In fact, the way this is set up, there is no pointer to the function anywhere which makes it an "anonymous function." In other words, as is, the function itself is un-exportable. Usually when you talk about exporting things, you're talking about exporting variables that you defined inside anonymous functions. For example, here I am exporting the function my_inner_function from an anonymous function.

(function (<ParameterA>) {
  // export this function here.
  window.my_inner_function = function() {
    ...
  };
})(<ParameterB>);

Usually, the point of anonymous functions is that you have all kinds of variables that you don't want to export because you don't want to possibly muck with other code.

(function (<ParameterA>) {
  // convert could be defined somewhere else too, so to be on the safe side
  // I will hide it here in my anonymous function so nobody else can
  // reference it.
  var convert = function() {
    ...
  };
})(<ParameterB>);

This is particularly important when you compress your Javascript and get function names like a and b.

(function (<ParameterA>) {
  // So compressed!
  var a = function() {
    ...
  };
})(<ParameterB>);

(function () {
  // Another compressed thing! Good thing these are hidden within anonymous
  // functions, otherwise they'd conflict!
  var a = function() {
    ...
  };
})();

Now this

(function (<ParameterA>) {

})(<ParameterB>);

is the same thing as

// Assume ParameterB is defined somewhere out there.
(function () {
  var ParameterA = ParameterB;
})();

Which gives you an idea why you'd use the parameters. You may find the parameter approach less confusing, or you may want to make it clear that you don't want to affect "by value" variables such as numbers and strings.

As others have pointed out, a || b is spoken as "a or b" and means "a if a evaluates to true, otherwise b, no matter what b is."

Edit

To answer your question, when you get to })(); the () causes the anonymous function to run. Remember that Javascript engines will first parse all code to make sure the syntax is correct, but won't actually evaluate/execute any code until it reaches that code. Hence, it's when the anonymous function runs that var ParameterA = ParameterB; gets evaluated. Here are some examples that hopefully help.

var ParameterB = "hello";

(function () {
  var ParameterA = ParameterB;
  // alerts "hello" because when this line is evaluated ParameterB is still
  // "hello"
  alert(ParameterA); 
})(); // () here causes our anonymous function to execute

ParameterB = "world";

Now in this example, the function is no longer anonymous because it has a pointer. However, it acts the same as the previous example.

var ParameterB = "hello";

var myFunction = function () {
  var ParameterA = ParameterB;
  // alerts "hello" because when this line is evaluated ParameterB is still
  // "hello"
  alert(ParameterA); 
};

myFunction();

ParameterB = "world";

In this example, I change the order of the last 2 lines and get different results.

var ParameterB = "hello";

var myFunction = function () {
  var ParameterA = ParameterB;
  // alerts "world" because when this line is evaluated ParameterB has
  // already changed.
  alert(ParameterA); 
};

// notice that I moved this line to occur earlier.
ParameterB = "world"; 

myFunction();


The code block above executes an anonymous function immediately after declaring it.

  1. ParameterA is a parameter to the anonymous function you are declaring
  2. ParameterB is the value you are passing to ParameterA

So the function you declared will be executed immediately, passing ParameterB as the value for ParameterA.

The jQuery || myFunc block means this: use jQuery as the argument unless it is not defined, in which case use myFunc.

Edit:

This is often used when defining jQuery plugins to avoid conflicts with the $ variable if multiple javascript libraries are being used. So you would make your plugin definition a function that accepts $ as a parameter, which you would execute immediately, passing jQuery as the value to $.

Example (from jQuery docs):

(function( $ ){
  $.fn.myPlugin = function() {
    // Do your awesome plugin stuff here
  };
})( jQuery );

The result of the above code block will be a plugin definition where you are guaranteed that $ will be an alias for jQuery.


For parts 1 and 2, ParameterA could be used to alias a nested hierarchy. (ie: YAHOO.util.Event passed in as ParameterB, can be used as "e" in ParameterA.) That way, inside the anonymous function, you wouldn't be typing out the full namespace path. [I know you're a jquery guy, but the yahoo namespace is longer, and illustrates the point better :)] Alternatively, you could just manually store the reference in a var inside the function.

the jquery || myFunc syntax is shorthand for "use jquery if it is truthy/available, or myFunc if it is not".

It's sort of like var toUse = jQuery !== undefined ? jQuery : myFunc;

This is because javascript allows falsy value evaluation without converting the objects fully to a boolean. ie: undefined is falsy, "" is falsy, null is falsy.

The alternative can be used to detect if a method or property is even available with &&.

ie: var grandParent = person && person.parent && person.parent.parent;

This will only be defined if the person has a parent, and their parent has a parent. Any failure along the && leading up to the last statement will result in grandParent being undefined.

Lastly, the parens around the || shortcut syntax are basically executing the function immediately after the declaration, passing the evaluated value into the anonymous function.

ie: (function(a, b) { return a + b; })(2,3)

Will immediately execute and return 5. In practice, this anonymous function execution could be used with the module pattern to establish a set of public methods which use private functions that themselves do not appear in the page's namespace. This is more in depth than your original question, but you can check out this article for more information: http://yuiblog.com/blog/2007/06/12/module-pattern/


ParameterA is referencing the value passed in at ParameterB. This:

(function (<ParameterA>) {

})(<ParameterB>);

Is sort of the same as this:

function test(<ParameterA>) {

}

test(<ParameterB>);

The difference is that this way you are using a closure to not have conflicting functions in the global namespace.

For the second part: the || work sort of like param = jQuery ? jQuery : myFunc. It passes in jQuery if it is defined, or myFunc if it isn't.


With your first part:

(function (<ParameterA>) {

})(<ParameterB>);

This means that the variable known as ParameterB outside the function will be known as ParameterA inside the function. This is known as a self-executing function, because the function is called as soon as it is defined. It means that you can use ParameterA inside the function without overriding a variable that exists outside the function.

For instance:

(function($){

})(jQuery);

This means that you can have $ as, for instance, Mootools outside the function and as jQuery inside it.

With your second part:

})(jQuery || myfunc);

This calls the function passing the jQuery variable if it exists, and myfunc if it does not. I don't quite know why you'd do this...

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜