`
该用户名已经存在
  • 浏览: 308594 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Javascript 中的即时函数和初始化分支

阅读更多
众所周知,在Javascript中,定义函数的方式有三种。
0. 定义函数的方式
//函数声明
function boo()
{
    //函数体
}

//函数表达式
var boo = function()
{
    //函数体
}

//命名函数表达式
var boo = function boo()
{
    //函数体
};

1. Javascript中,还有一种函数的表现形式就是即时函数。顾名思义,即时函数就是可以在页面加载完该函数之后立即执行该函数的语法。
即时函数的写法:
    //即时函数是一种支持在定义函数侯立即执行该函数的一种语法。
    (function()
    {
        alert("immediate function");
    }());

    //也可以写成
    (function()
    {
        alert("immediate function");
    })();

2. 注意:即时函数是该函数加载完就会立即被执行,而不是等待页面加载完之后才执行即时函数,这和window.onload()和$(function(){})都是有区别的,所以即时函数是不能替代以上两者的,举个例子:
<html>
    <head>
    <title>即时函数</title>
    <script language="javascript" type="text/javascript">
        (function()
        {
             alert(document.getElementsByTagName("body")[0]);
             //undefined,因为这个时候DOM元素<body>还没有被加载。
        })();
        
        //另一种方式
         window.onload = function()
        {
            (function()
            {
                 alert(document.getElementsByTagName("body")[0]);
                 //object, 因为window.onload是要等待页面的所以元素加载完
                    //才会执行的。
              })();
        };
    </script>
    </head>
    <body>
    </body>
</html>

3. 即时函数的意义,比如在页面加载时,必须执行一些任务,如附加事件处理程序,创建对象等任务,这些任务只需要执行一次,因此没有必要创建一个命名函数,而且这些初始化任务也需要一些变量,将这些变量定义到全局对象中是一个不完美的方法,因为这些变量也是只需要一次,应当尽量保持全局空间的洁净。那么这样的任务就可以用即时函数完成。
举例说明:
    //即时函数能保持全局空间不受污染,能立即执行,可作为一些初始化工作,
     //即时函数是非常有用的。
    (function()
    {
        var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
        today = new Date(),
        msg = "Today is " + days[today.getDay()] + 
               ", " + today.getDate();
        
        alert(msg);
        
    })(); //Today is Sun, 25

4. 即时函数能够访问全局空间的函数,支持参数传递和返回值。
    //全局空间里的函数
    var global_f = function()
    {
        alert("global scope");
    };

    //即时函数返回值,参数。
    var result_f = (function(param)
    {
         alert(param); //param
         global_f(); //global scope
         
         return function()
         {
            return 2;
         };
         
    }("param"));
    
    result_f(); //2

5. 即时函数也可以用于创建对象属性,比如,某个对象的某个属性在对象生命周期内都不会改变,但是该属性值的获取需要做一些工作。我们就可以通过即时函数的方式,将即时函数的返回值作为该属性的值。
    //定义对象时使用即时函数
    var obj = 
    {
        msg: (function()
        {
            //获取该对象属性需要做的一些工作
            var what = "call", who = "me";
            
            return what + " " + who;
        })(), 
        
        getMsg: function()
        {
            return this.msg;
        }
    };

6. 采用即时函数处理一些初始化任务是一个不错的方法,但是在初始化任务很复杂的情况下,采用即时函数可能导致代码凌乱,函数中可能充斥着很多零散的变量和方法。为了使初始化任务代码更加的模块化,可以采用即时对象初始化的方法。
该模式就是创建一个临时对象,创建完该临时对象后立即执行该对象的某个方法(该方法通常定义为init方法)进行初始化工作。
    //即时对象初始化
    ({
        maxwidth: 400,
        maxheight: 180,
        getMax: function()
        {
            return this.maxwidth + "x" + this.maxheight;
        },
        init: function()
        {
            //初始化任务
            alert(this.getMax());
        }
         
    }).init();

7. 初始化分支,初始化分支又称为加载时分支,是一种初始化优化模式。当知道某个条件在整个程序生命周期都不会发生改变的时候,我们仅仅只需要对该条件判断一次就可以了。先看一下没有初始化分支的效果
例如:
    var utils = 
    {
        addListener: function(_el, _type, _fn)
        {
            if (typeof window.addEventListener === "function")
            {
                _el.addEventListener(_type, _fn, false);       
            }
            else if(typeof document.attachEvent === "function") //IE
            {
                _el.attachEvent("on" + _type, fn)
            }
            else
            {
                _el["on" + _type] = _fn; //更早版本的浏览器 
            }
        },
        
        removeListener: function(_el, _type, _fn)
        {
            if (typeof window.addEventListener === "function")
            {
                _el.removeEventListener(_type, _fn, false);       
            }
            else if(typeof document.attachEvent === "function") //IE
            {
                _el.detachEvent("on" + _type, fn)
            }
            else
            {
                _el["on" + _type] = null; //更早版本的浏览器 
            }
        }
    };

以上代码的问题在于,每次在调用utils.addListener或utils.removeListener时,都会重复的执行想同的检查,效率是比较低下的。


下面将采用初始化分支解决这个问题。
    //接口
    var util = 
    {
        addListener: null,
        removeListener: null
    };
    
    //初始化分支实现
    if (typeof window.addEventListener === "function")
    {
        util.addListener = function(_el, _type, _fn)
        {
             _el.addEventListener(_type, _fn, false);  
        };
        util.removeListener = function(_el, _type, _fn)
        {
             _el.removeEventListener(_type, _fn, false);  
        }; 
    }
    else if(typeof document.attachEvent === "function")
    {
        util.addListener = function(_el, _type, _fn)
        {
             _el.attachEvent("on" + _type, fn);
        };
        util.removeListener = function(_el, _type, _fn)
        {
             _el.detachEvent("on" + _type, fn);
        };
    }
    else
    {
        util.addListener = function(_el, _type, _fn)
        {
             _el["on" + _type] = _fn;
        };
        util.removeListener = function(_el, _type, _fn)
        {
            _el["on" + _type] = null;
        };
    }

以上通过初始化分支后,util的addListener和removeListener方法只被初始化一次,以后的每次调用不必再重复的做浏览器版本判断了。
分享到:
评论
1 楼 wukele 2012-12-03  
不错

相关推荐

    JavaScript模式中文[pdf] 百度云

     初始化时分支  函数属性——备忘模式  配置对象  Curry  小结  第5章 对象创建模式  命名空间模式  声明依赖关系  私有属性和方法  模块模式  沙箱模式  静态成员  对象常量  链模式  method()方法 ...

    JavaScript模式 斯托扬·斯特凡洛夫 著

    初始化时分支 函数属性——备忘模式 配置对象 Curry 小结 第5章 对象创建模式 命名空间模式 声明依赖关系 私有属性和方法 模块模式 沙箱模式 静态成员 对象常量 链模式 method()方法 小结 第6章 代码复用模式 传统...

    一个微型库用于在JavaScript中构建响应式类似于电子表格的计算器

    1. **初始化单元格**:创建新的单元格对象,并设置其初始值或计算公式。 2. **设置公式**:在单元格中定义计算公式,可以引用其他单元格,支持常见的数学运算符和函数。 3. **建立依赖关系**:当一个单元格的值改变...

    DesignPatterns[removed]JavaScript设计模式

    初始化分支是一种优化模式,当知道某个条件在整个生命周期内都不会发生变化时,仅对该条件测试一次。 cachefunction.js 备忘模式 让复杂的操作缓存在函数的属性中,从而只需要执行一遍。 typicalapp.js tom大叔曾经...

    JavaScript基础教程

    - **undefined**:表示未初始化的变量。 **4.2 变量** - **变量命名规则**:必须以字母、下划线或美元符号开头。 - **声明变量**:使用`var`、`let`或`const`关键字。 - **变量赋值**:使用`=`运算符。 - **变量...

    web嵌入json编辑器

    2. **初始化编辑器**:在JavaScript中创建一个元素作为编辑器的容器,并调用JSON编辑器的初始化函数,传入配置参数。 3. **设置和获取数据**:使用提供的API来设置初始JSON数据,以及获取编辑后的数据。 4. **事件...

    javascript设计模式 – 单例模式原理与应用实例分析

    在JavaScript中,这通常通过即时执行函数(IIFE)来实现,以保证私有变量和全局访问点。当单例模式被实现后,整个系统在任何时候都应该能通过全局访问点获得相同的实例。 在JavaScript中实现单例模式有两大分支:...

    catalogo_educativo:HTML,CSS3,JavaScript和Biblioteca JQuery的目录网络

    - JavaScript基本语法,包括DOM操作、事件处理和函数 - JQuery库的使用,如选择器、方法和插件 - 如果存在,了解AJAX和JSON数据格式 总的来说,"catalogo_educativo"是一个实践这些技术的好机会,通过学习和改进这...

    2021-2022计算机二级等级考试试题及答案No.4826.docx

    20. **数组初始化**:此题涉及数组初始化,输出为21,因为数组的下标从0开始,所以实际累加到第5个元素。 21. **VBA程序流程控制**:VBA支持顺序、分支和循环三种控制方式。 22. **运算器功能**:运算器不仅执行...

    常用JS代码

    JavaScript支持以下数据类型:`String`(字符串)、`Number`(数字)、`Boolean`(布尔值)、`Null`(空)、`Object`(对象)和`Function`(函数)。理解这些类型对于编写有效的脚本至关重要。 ### 8. 类型转换:`...

    dealerware

    首先,我们来看如何初始化和运行这个项目。在描述中提到的"yarn install"命令,它是Yarn包管理器的一个常用命令,用于安装项目中`package.json`文件里列出的所有依赖项。Yarn是JavaScript社区中广泛使用的替代npm...

    tommy.js:在您编写代码时批评您的 jQuery 插件!

    5. **插件开发**:了解jQuery插件的结构、命名空间、初始化、公共方法和私有方法等设计原则。 6. **最佳实践**:遵循的编码和设计标准,如避免全局变量、减少DOM操作、使用高效的算法等。 7. **错误和警告**:如何...

    reagent-games:写成试剂练习的小游戏合集

    6. **项目结构与模板**:理解如何组织一个ClojureScript项目,以及如何利用模板快速初始化新项目。 7. **版本控制**:了解Git的基础知识,包括提交、分支、合并和解决冲突。 通过这个项目,开发者不仅可以提升...

    SWITCH-NG:一家电子商务商店

    在深入代码之前,开发者可能需要先了解项目结构,查看README文件以获取项目初始化、安装依赖和运行的指南。JavaScript 文件通常位于项目中的 "src" 或 "js" 目录下,而配置文件可能在 "config" 目录中。HTML 和 CSS ...

    beneDitto:基于Pokemon的Discord机器人游戏

    5. `bot.js`或`index.js`:主入口文件,启动和初始化Discord机器人。 6. `commands/`:存储机器人命令处理函数的目录,每个子文件可能对应一个特定的命令。 7. `data/`:可能包含Pokemon相关的数据文件,如精灵列表...

    react-firechat:创建第一个React Firebase项目是为了在职业培训课程中学习如何使用这些技术

    2. **安装和配置React**:学习如何使用`create-react-app`脚手架快速初始化一个React项目,理解项目的目录结构和配置文件。 3. **使用Firebase**:注册Firebase账户,创建新项目,设置Realtime Database规则,并...

    MobileFinal:移动网络应用-使用Google地图搜索您附近的服务。 使用Angular.js构建。 在http上实时查看

    1. `index.html` - 应用的主入口文件,包含HTML结构和Angular.js的初始化。 2. `app.js` - 应用的核心JavaScript文件,定义了Angular.js模块、控制器、服务等。 3. `controllers.js` - 包含控制地图显示、搜索等功能...

    SpeedSearch:一款可让您真正快速地开始搜索列表的应用程序

    2. `index.html`:项目的主入口文件,用于初始化和渲染应用程序。 3. `package.json`:定义项目依赖和脚本的配置文件,用于npm(Node.js包管理器)管理。 4. `README.md`:介绍项目、安装步骤和使用方法的文档。 5. ...

    sitecore-live-blog:使用SignalR和Sitecore的实时博客

    这通常包括初始化连接,定义接收消息的回调函数,以及处理可能出现的连接错误。此外,前端UI也需要相应地设计和更新,以便正确显示实时更新的内容。 Sitecore-live-blog-master这个文件名暗示了这是一个GitHub仓库...

Global site tag (gtag.js) - Google Analytics