zoukankan      html  css  js  c++  java
  • js 闭包 匿名函数 JavaScript的IIFE(即时执行方法)immediately-invoked function expression

    参考:http://segmentfault.com/a/1190000000348228

    http://segmentfault.com/q/1010000000442042

    问题:

    (function(){
    function a(){
       alert("a");
    }
    })();
    这里的(function(){xxx})(); 是什么意思,为什么这么写,有什么好处?
    答:
    function foo() {...}     // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。
    
    foo();                   // 这是语句,Statement;解释器遇到语句是会运行它的。
    (1)标准写法 
    Js代码  收藏代码
    1. (function (window, document, undefined) {  
    2.   //   
    3. })(window, document);  
    
    

    (2)作用域Scope 
    JavaScript有function作用域,所以function首先创建一个私有的作用域,在执行的时候都会创建一个执行上下文。
    Js代码  收藏代码
    1. (function (window, document, undefined) {  
    2.   var name = '张三';  
    3. })(window, document);  
    4. console.log(name); // 因为作用域不同,这里的name未定义。  
    
    

    调用方法一: 
    Js代码  收藏代码
    1. var logMyName = function (name) {  
    2.   console.log(name);  
    3. };  
    4. logMyName('李四');  
    
    

    调用方法二: 
    Js代码  收藏代码
    1. var logMyName = (function (name) {  
    2.   console.log(name);  
    3. })('王五');  
    
    

    需要注意的是需要用括号把函数内容括起来: 
    Js代码  收藏代码
    1. function () {  
    2.   // ...  
    3. })();  
    
    

    没有括号的话会报语法错: 
    Js代码  收藏代码
    1. function () {  
    2.   // ...  
    3. }();  
    
    

    也可以强制JavaScript识别代码(一般很少这么用): 
    Js代码  收藏代码
    1. !function () {  
    2.   // ...  
    3. }();  
    4.   
    5. +function () {  
    6.   // ...  
    7. }();  
    8.   
    9. -function () {  
    10.   // ...  
    11. }();  
    12.   
    13. ~function () {  
    14.   // ...  
    15. }();  
    
    

    比如: 
    Js代码  收藏代码
    1. var a = !function () {  
    2.     return true;  
    3. }();  
    4. console.log(a); // 打印输出 false  
    5.   
    6. var b = (function () {  
    7.     return true;  
    8. })();  
    9. console.log(b); // 打印输出 true  
    
    

    (3)参数Arguments 

    传递参数给IIFE 
    Js代码  收藏代码
    1. (function (window) {  
    2.   // 这里可以调用到window  
    3. })(window);  
    4.   
    5. (function (window, document) {  
    6.   // 这里可以调用到window和document  
    7. })(window, document);  
    
    

    undefined参数 
    在ECMAScript 3中undefined是mutable的,这意味着可以给undefined赋值,而在ECMASCript 5的strict模式('use strict';)下是不可以的,解析式时会报语法错。 

    所以为了保护IIFE的变量需要undefined参数: 
    Js代码  收藏代码
    1. (function (window, document, undefined) {  
    2.   // ...  
    3. })(window, document);  
    
    

    即使有人给undefined赋值也没有关系: 
    Js代码  收藏代码
    1. undefined = true;  
    2. (function (window, document, undefined) {  
    3.   // undefined指向的还是一个本地的undefined变量  
    4. })(window, document);  
    
    

    (4)代码压缩Minifying 
    Js代码  收藏代码
    1. (function (window, document, undefined) {  
    2.   console.log(window); // window对象  
    3. })(window, document);  
    
    代码压缩后,undefined的参数不再存在,但是由于 (window, document); 的调用没有传递第三个参数,所有c依然是一个本地undefined变量,所有参数中undefined的名字是无所谓什么的,只需要知道他指向的是一个undefined变量。 
    Js代码  收藏代码
    1. (function (a, b, c) {  
    2.   console.log(a); // window对象  
    3. })(window, document);  
    
    

    除undefined变量外,其他的所有希望只在函数内部有效的变量都可以通过参数传递进去,比如以下的jQuery对象。 
    Js代码  收藏代码
      1. (function ($, window, document, undefined) {  
      2.   // 使用 $ 指向 jQuery,比如:  
      3.   // $(document).addClass('test');  
      4. })(jQuery, window, document);  
      5.   
      6. (function (a, b, c, d) {  
      7.   // 代码会被压缩为:  
      8.   // a(c).addClass('test');  
      9. })(jQuery, window, document);  
     

    (function(){}) 这样就是一个表达式

    (function(){
        var r, url;                   
        var s = location.href;
        url = /http://www.csdn.com.cn/i;          
        if(s.search(url)>=0){
          var head=document.getElementById("topHead");
          head.style.width="990px";
        }
      })
    声明了一个匿名函数
    加个()执行它

    就是不需要方法名,直接创建以后调用

    function a(){alert()} 
    a() //执行该方法
     
    function{return alert()}() //直接执行该方法
  • 相关阅读:
    for of 与 for in的区别2
    jQuery的deferred对象详解
    poj 3128 Leonardo's Notebook(置换的幂)
    解决shell脚本中 echo 怎么写入换行到文件
    【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
    iOS中怎样加入自己定义的字体
    Android学习笔记(十四)——在执行时加入碎片(附源代码)
    Threads and Anonymous Classes in JAVA
    与一线Linux嵌入式开发project师的对话
    公司实习经验分享
  • 原文地址:https://www.cnblogs.com/xiaodoujiaohome/p/5016885.html
Copyright © 2011-2022 走看看