关于(function(){})()

来源:互联网 发布:cg软件 编辑:程序博客网 时间:2024/05/19 12:40

话不多说,先看代码

<script>    getajax = (function(){        alert("hello");        function dosomething(){            alert("world");        }        return {do : dosomething};    })();//此处函数已经执行完毕,所以getajax是返回值,而不是函数    getajax.do();//此处执行dosomething函数</script>

此处代码的执行结果会弹出两条语句,”hello”和“world”
getajax是一个变量,是函数的返回值,是对象{do: dosomething},

var hello = function(){ };或function hello(){};

是函数声明方法,只会声明函数,而不会执行函数

var hello = function(){ }; 或 function hello(){ };hello();

上文中hello()才会执行函数
但是这样的函数声明需要一个全局变量才能调用,如是人们想,

function(){}();

这样是不是可以呢?很可惜,这样是不行的,因为function(){}只是函数声明语句,编译器会认为在函数声明语句后面直接加()是语法错误。

(function(){})();

上面加了括号之后编译器会认为上文是一个表达式,会按表达式的方式立即执行函数,所以上文可以。实际上,生成表达式的方式很多,比如

(function(){}());+function(){}();!function(){}();void(function(){}());

都可以,注意void不会返回返回值。
文章最开始的代码,因为getajax= 后面已经是表达式了,所以,下面的代码会产生同样的结果

<script>    getajax = function(){        alert("hello");        function dosomething(){            alert("world");        }        return {do:dosomething};    }();    getajax.do();

如果去掉了

getajax = 

那么括号就是必须的,否则编译器会认为这是一个函数声明语句,而后面的括号是语法错误。
此处的getajax是用来接收函数的返回值的,它不是一个函数,是一个对象,即{ do:dosomething}。

OVER

续:09/05/2016
前文讲到如何在声明函数后立即执行函数,那么如何如果要向声明的函数传递参数要怎么办呢,

(function(param) {    alert(param);})("hello");

只需要在括号中传入相应的参数即可。
在js中,参数不仅可以是string,还可以是对象,于是

(function($){...})(jQuery);

这个方法将jQuery对象作为参数传入函数,而jQuerynoconflict使,防止与其它js类库冲突。
还可以更进一步,使用函数作为函数的参数

(function(factory){    factory("hello");})(function(para){    alert(para);    });

此处将匿名函数
function(para){alert(para);}
作为参数传入第一个函数,factory是形参,而匿名函数是实参,在第一个函数内部再次调用匿名函数。所以我们也可以这样

(function(factory){    factory(jQuery);    })(function($){...})

这样,可以在第一个匿名函数内将jQuery传入第二个匿名函数,而在第二个函数内部使用传入不同的实参,可以是jQuery,也可以是其它的prototype等。

小结:(function(){})()本来是非常简单的声明完成执行,但是由于js参数类型的多变,形成了非常复杂与多变的结构,但其最初的原理还是一样。

0 0
原创粉丝点击