javascript自动执行函数(立即调用函数)

Young      2022-02-10     451

关键词:

开头:各种原因总结一下javascript中的自动执行函数(立即调用函数)的一些方法,正文如下

    在Javascript中,任何function在执行的时候都会创建一个执行上下文,因为function声明变量和function有可能只在该function内部,这个上下文,在调用function的时候,提供一些简单的方式来创建自由变量或私有子function。

eg:

// 由于该function里返回了另外一个function,其中这个function可以访问自由变量i
// 所有说,这个内部的function实际上是有权限可以调用内部的对象。
function makeCounter() {
// 只能在makeCounter内部访问i
 var i = 0;
return function () {
console.log(++i);
};
}
// 注意,counter和counter2是不同的实例,分别有自己范围内的i。
var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
var counter2 = makeCounter();
counter2(); // logs: 1
counter2(); // logs: 2
alert(i); // 引用错误:i没有defind(因为i是存在于makeCounter内部)。

正文核心
1、Javascript方法:
       在声明类似function foo(){}或var foo = function(){}函数的时候,通过在后面加个括弧就可以实现自执行,例如foo(),看代码:
// 因为想下面第一个声明的function可以在后面加一个括弧()就可以自己执行了,比如foo(),
// 因为foo仅仅是function() { /* code */ }这个表达式的一个引用
var foo = function(){ /* code */ }
// ...是不是意味着后面加个括弧都可以自动执行?
function(){ /* code */ }(); // SyntaxError: Unexpected token (
        上述代码,如果甚至运行,第2个代码会出错,因为在解析器解析全局的function或者function内部function关键字的时候,默认是认为function声明,而不是function表达式,如果你不显示告诉编译器,它默认会声明成一个缺少名字的function,并且抛出一个语法错误信息,因为function声明需要一个名字。        有趣的是,即便你为上面那个错误的代码加上一个名字,他也会提示语法错误,只不过和上面的原因不一样。在一个表达式后面加上括号(),该表达式会立即执行,但是在一个语句后面加上括号(),是完全不一样的意思,他的只是分组操作符。
// 下面这个function在语法上是没问题的,但是依然只是一个语句
// 加上括号()以后依然会报错,因为分组操作符需要包含表达式  
 function foo(){ /* code */ }(); // SyntaxError: Unexpected token )  
// 但是如果你在括弧()里传入一个表达式,将不会有异常抛出
// 但是foo函数依然不会执行 
function foo(){ /* code */ }( 1 );  
// 因为它完全等价于下面这个代码,一个function声明后面,又声明了一个毫无关系的表达式:  
function foo(){ /* code */ } 
( 1 );
你可以访问ECMA-262-3 in detail. Chapter 5. Functions 获取进一步的信息。
          要解决上述问题,非常简单,我们只需要用大括弧将代码的代码全部括住就行了,因为JavaScript里括弧()里面不能包含语句,所以在这一点上,解析器在解析function关键字的时候,会将相应的代码解析成function表达式,而不是function声明。
// 下面2个括弧()都会立即执行  
(function () { /* code */ } ()); // 推荐使用这个 
(function () { /* code */ })(); // 但是这个也是可以用的  
// 由于括弧()和JS的&&,异或,逗号等操作符是在函数表达式和函数声明上消除歧义的 
// 所以一旦解析器知道其中一个已经是表达式了,其它的也都默认为表达式了 
// 不过,请注意下一章节的内容解释  
var i = function () { return 10; } (); 
true && function () { /* code */ } ();
0, function () { /* code */ } ();

// 如果你不在意返回值,或者不怕难以阅读 
// 你甚至可以在function前面加一元操作符号  
!function () { /* code */ } (); 
~function () { /* code */ } (); 
-function () { /* code */ } (); 
+function () { /* code */ } ();
// 还有一个情况,使用new关键字,也可以用,但我不确定它的效率 
// http://twitter.com/kuvos/status/18209252090847232  
new function () { /* code */
new function () { /* code */ } () // 如果需要传递参数,只需要加上括弧()
        上面所说的括弧是消除歧义的,其实压根就没必要,因为括弧本来内部本来期望的就是函数表达式,但是我们依然用它,主要是为了方便开发人员阅读,当你让这些已经自动执行的表达式赋值给一个变量的时候,我们看到开头有括弧(,很快就能明白,而不需要将代码拉到最后看看到底有没有加括弧。

用闭包保存状态

        和普通function执行的时候传参数一样,自执行的函数表达式也可以这么传参,因为闭包直接可以引用传入的这些参数,利用这些被lock住的传入参数,自执行函数表达式可以有效地保存状态。

// 这个代码是错误的,因为变量i从来就没背locked住 
// 相反,当循环执行以后,我们在点击的时候i才获得数值 
// 因为这个时候i操真正获得值 
// 所以说无论点击那个连接,最终显示的都是I am link #10(如果有10个a元素的话)  var elems = document.getElementsByTagName('a');  
for (var i = 0; i < elems.length; i++) { elems[i].addEventListener('click', function (e) { e.preventDefault();  
alert('I am link #' + i); }, 'false'); 
}
// 这个是可以用的,因为他在自执行函数表达式闭包内部 
// i的值作为locked的索引存在,在循环执行结束以后,尽管最后i的值变成了a元素总数
// 但闭包内部的lockedInIndex值是没有改变,因为他已经执行完毕了 
// 所以当点击连接的时候,结果是正确的  
var elems = document.getElementsByTagName('a'); 
for (var i = 0; i < elems.length; i++) {  
(function (lockedInIndex) { elems[i].addEventListener('click', function (e) { e.preventDefault();  
alert('I am link #' + lockedInIndex); }, 'false'); 
})(i); }  
// 你也可以像下面这样应用,在处理函数那里使用自执行函数表达式 
// 而不是在addEventListener外部 
// 但是相对来说,上面的代码更具可读性  
var elems = document.getElementsByTagName('a');  
for (var i = 0; i < elems.length; i++) { elems[i].addEventListener('click', (function (lockedInIndex) { return function (e) {  
 e.preventDefault();  
 alert('I am link #' + lockedInIndex);  
 };  
})(i), 'false');  
}
其实,上面2个例子里的lockedInIndex变量,也可以换成i,因为和外面的i不在一个作用于,所以不会出现问题,这也是匿名函数+闭包的威力。 自执行匿名函数和立即执行的函数表达式区别           在这篇帖子里,我们一直叫自执行函数,确切的说是自执行匿名函数(Self-executing anonymous function),但英文原文作者一直倡议使用立即调用的函数表达式(Immediately-Invoked Function Expression)这一名称,作者又举了一堆例子来解释,好吧,我们来看看:
// 这是一个自执行的函数,函数内部执行自身,递归 
function foo() { foo(); } 
// 这是一个自执行的匿名函数,因为没有标示名称 
// 必须使用arguments.callee属性来执行自己 
var foo = function () { arguments.callee(); };  
// 这可能也是一个自执行的匿名函数,仅仅是foo标示名称引用它自身 
// 如果你将foo改变成其它的,你将得到一个used-to-self-execute匿名函数 
var foo = function () { foo(); };  
// 有些人叫这个是自执行的匿名函数(即便它不是),因为它没有调用自身,它只是立即执行而已。 (function () { /* code */ } ());  
// 为函数表达式添加一个标示名称,可以方便Debug 
// 但一定命名了,这个函数就不再是匿名的了 
(function foo() { /* code */ } ());  
// 立即调用的函数表达式(IIFE)也可以自执行,不过可能不常用罢了 
(function () { arguments.callee(); } ()); (function foo() { foo(); } ());  
// 另外,下面的代码在黑莓5里执行会出错,因为在一个命名的函数表达式里,他的名称是undefined 
(function foo() { foo(); } ());

希望这里的一些例子,可以让大家明白,什么叫自执行,什么叫立即调用。

注意:arguments.callee在ECMAScript 5 strict mode里被废弃了,所以在这个模式下,其实是不能用的。

在JS中最简单的调用方式,直接写到html的body标签里面:
<body onload="myfunction()">
<html> <body onload="func1();func2();func3();"> </body> </html>
在JS中调用方式: 
  <script type="text/javascript">
   function myfun() 

{    alert("this window.onload");   }   /*用window.onload调用myfun()*/

    window.onload = myfun;//不要括号
 </script> 
 <script type="text/javascript">
    window.onload=function(){
      func1();
      func2();
     func3(); }
 </script>

2、JQ方法  

1)整个页面的document全部加载完成以后执行。不幸的这种方式不仅要求页面的DOM tree全部加载完成,而且要求所有的外部图片和资源全部加载完成。更不幸的是,如果外部资源,例如图片需要很长时间来加载,那么这个js方法执行感觉就比较慢了。也就是说这是一种最严谨的页面加载完再执行方法的方法。 window.onload =function() { $("table tr:nth-child(even)").addClass("even"); //这个是jquery代码 };

2)仅只需要加载所有的DOM结构,在浏览器把所有的HTML放入DOM tree之前就执行方法。包括在加载外部图片和资源之前。 $(document).ready(function() { $("table tr:nth-child(even)").addClass("even"); //任何需要执行的js特效 });

3)还有一种简写方式 $(function() { $("table tr:nth-child(even)").addClass("even"); //任何需要执行的js特效 });

参考:http://www.jb51.net/article/81724.htm
http://blog.csdn.net/limlimlim/article/details/9198111

http://www.cnblogs.com/ayning/p/4113314.html 








理解javascript的立即调用函数表达式(iife)

首先这是js的一种函数调用写法,叫立即执行函数表达式(IIFE,即immediately-invokedfunctionexpression)。顾名思义IIFE可以让你的函数立即得到执行(废话)。一般来说,IIFE有以下几种用途:  1.创建只使用一次的函数,并立即执行它。 ... 查看详情

js立即执行函数

javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解。(function(){…})()和(function(){…}())是两种javascript立即执行... 查看详情

深入理解javascript中的立即执行函数(function(){…})()

这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以参考下http://www.jb51.net/article/50967.htm javascript和其他... 查看详情

javascript中的立即执行函数(代码片段)

通常我们声明一个函数有以下几种方式://声明函数f1functionf1()console.log("f1");//通过()来调用此函数f1();//一个匿名函数的函数表达式,被赋值给变量f2:varf2=function()console.log("f2");//通过()来调用此函数f2();//一个... 查看详情

javascript函数

  函数跟随一对圆括号()表示函数调用//函数声明语句写法functiontest(){};test();//函数表达式写法vartest=function(){};test();  但有时需要在定义函数之后,立即调用该函数。这种函数就叫做立即执行函数,全称为立即调用的函数表... 查看详情

javascript学习-46.立即执行函数(代码片段)

前言立即执行函数有以下作用创建一个独立作用域,这个作用域里面的变量,外部访问不到,避免变量污染。闭包和私有数据使用语法有两种写法//第一种:用括号把整个函数定义和括号调用包裹起来(function()//函... 查看详情

深入理解javascript

立即调用的函数表达式前言大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行。在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法也不一定完全对... 查看详情

javascript要点(上)

立即执行函数即ImmediatelyInvokedFunctionExpression(IIFE),正如它的名字,就是创建函数的同时立即执行。它没有绑定任何事件,也无需等待任何异步操作:(function(){console.log("js")})()function(){…}是一个匿名函数,包围它的一对括号将其转... 查看详情

自动执行javascript函数并稍后调用它们?

】自动执行javascript函数并稍后调用它们?【英文标题】:Auto-executejavascriptfunctionsANDcallthemlater?【发布时间】:2012-05-2901:23:34【问题描述】:我在很多地方读到过,您可以通过以下方式在加载时自动启动js函数:$(function()//code...);... 查看详情

javascript立即执行函数表达式(iife)

...e*/})();Q:为什么这样写,函数就嗯那个立即执行?A:因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。eg:... 查看详情

深入理解javascript中的立即执行函数(function()…)()(代码片段)

javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解。(function()…)()和(function()…())是两种javascript立即... 查看详情

(转)扫盲--javascript的立即执行函数

看过jQuery源码的人应该知道,jQuery开篇用的就是立即执行函数。立即执行函数常用于第三方库,好处在于隔离作用域,任何一个第三方库都会存在大量的变量和函数,为了避免变量污染(命名冲突),开发者们想到的解决办法就... 查看详情

javascript函数声明,函数表达式,匿名函数的区别,深入理解立即执行函数(function(){…})()

functionfnName(){xxxx};//函数声明:使用function关键字声明一个函数,在指定一个函数名。//例如:(正常,因为提升了函数声明,函数调用可以在函数声明之前)fnName();functionfnName(){alert(‘HelloWorld‘);}varfnName=function(){xxxx};//函数表达式:... 查看详情

javascript闭包和立即执行函数的作用

一、闭包——closure  先看一个闭包的例子。我们想实现一个计数器,最简单的方法就是定义一个全局变量,计数的时候将其加1。但是全局变量有风险,哪里都有可能不小心改掉它。那局部变量呢,它只在函数内部有效,函数... 查看详情

js基础_立即执行函数

1<!DOCTYPEhtml>2<html>3<head>4<metacharset="UTF-8">5<title></title>6<scripttype="text/javascript">789//函数对象()10/*11*立即执行函数12*函数定义完,立即被调用,这种函数叫做立即执行函数13*立即执行函数 查看详情

javascript--立即执行函数

  当函数被包含在一堆括号()内部就称为了一个表达式,通过在末尾上加上另一个()可以立即执行这个函数,这样的表达式就叫做立即执行函数表达式(ImmediatelyInvokedFunctionExpression,简称IIFE),如:(function(){...})()或者(function(){...}... 查看详情

javascript要点1

1.IIFE(立即执行函数)  立即执行函数,即ImmediatelyInvokedFunctionExpression(IIFE),正如它的名字,就是创建函数的同时立即执行。它没有绑定任何事件,也无需等待任何异步操作:    (function(){    //代码  })();  funct... 查看详情

javascript深入理解

立即调用的函数表达式前言大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行。在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法也不一定完... 查看详情