JavaScript惰性函数定义

函数是js世界的一等公民,js的动态性、易变性在函数的应用上,体现的淋漓尽致。做为参数,做为返回值等,正是函数这些特性,使得js开发变的有趣。

下面就阐述一下,js一个有趣的应用--惰性函数定义(Lazy Function Definition)。

惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了。

下面我们看几个典型的例子:

 1 function addEvent (type, element, fun) {
 2     if (element.addEventListener) {
 3         element.addEventListener(type, fun, false);
 4     }
 5     else if(element.attachEvent){
 6         element.attachEvent(‘on‘ + type, fun);
 7     }
 8     else{
 9         element[‘on‘ + type] = fun;
10     }
11 }

上面是注册函数监听的各浏览器兼容函数。由于,各浏览之间的差异,不得不在用的时候做能力检测。显然,单从功能上讲,已经做到了兼容浏览器。

美中不足,每次绑定监听,都会对能力做一次检测。然而,真正的应用中,这显然是多余的,同一个应用环境中,其实只需要检测一次即可。

下面我们重写上面的addEvent:

 1 function addEvent (type, element, fun) {
 2     if (element.addEventListener) {
 3         addEvent = function (type, element, fun) {
 4             element.addEventListener(type, fun, false);
 5         }
 6     }
 7     else if(element.attachEvent){
 8         addEvent = function (type, element, fun) {
 9             element.attachEvent(‘on‘ + type, fun);
10         }
11     }
12     else{
13         addEvent = function (type, element, fun) {
14             element[‘on‘ + type] = fun;
15         }
16     }
17     return addEvent(type, element, fun);
18 }

由上,第一次调用addEvent会对浏览器做能力检测,然后,重写了addEvent。下次再调用的时候,由于函数被重写,不会再做能力检测。

同样的应用,javascript高级程序设计里的一例子:

 1 function createXHR(){
 2     if (typeof XMLHttpRequest != "undefined"){
 3         return new XMLHttpRequest();
 4     } else if (typeof ActiveXObject != "undefined"){
 5         if (typeof arguments.callee.activeXString != "string"){
 6             var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
 7                             "MSXML2.XMLHttp"];
 8
 9             for (var i=0,len=versions.length; i < len; i++){
10                 try {
11                     var xhr = new ActiveXObject(versions[i]);
12                     arguments.callee.activeXString = versions[i];
13                     return xhr;
14                 } catch (ex){
15                     //skip
16                 }
17             }
18         }
19
20         return new ActiveXObject(arguments.callee.activeXString);
21     } else {
22         throw new Error("No XHR object available.");
23     }
24 }

很显然,惰性函数在这里优势更加明显,因为这里有更多的分支。下面我们看一下重写后台的函数:

 1 function createXHR() {
 2             if (typeof XMLHttpRequest != "undefined") {
 3                 createXHR = function () {
 4                     return new XMLHttpRequest();
 5                 }
 6                 return new XMLHttpRequest();
 7             } else if (typeof ActiveXObject != "undefined") {
 8                 var curxhr;
 9                 var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
10                     "MSXML2.XMLHttp"];
11
12                 for (var i = 0, len = versions.length; i < len; i++) {
13                     try {
14                         var xhr = new ActiveXObject(versions[i]);
15                         curxhr = versions[i];
16                         createXHR = function () {
17                             return new ActiveXObject(curxhr);
18                         }
19                         return xhr;
20                     } catch (ex) {
21                         //skip
22                     }
23                 }
24             } else {
25                 throw new Error("No XHR object available.");
26             }
27         }

浏览器之间最大的差异,莫过于Dom操作,Dom操作也是前端应用 中最频繁的操作,前端的大多性能提升,均体现在Dom操作方面。

下面看一个Dom操作方面的惰性函数定义例子:

 1 var getScrollY = function() {
 2
 3     if (typeof window.pageYOffset == ‘number‘) {
 4
 5         getScrollY = function() {
 6             return window.pageYOffset;
 7         };
 8
 9     } else if ((typeof document.compatMode == ‘string‘) &&
10                (document.compatMode.indexOf(‘CSS‘) >= 0) &&
11                (document.documentElement) &&
12                (typeof document.documentElement.scrollTop == ‘number‘)) {
13
14         getScrollY = function() {
15             return document.documentElement.scrollTop;
16         };
17
18     } else if ((document.body) &&
19                (typeof document.body.scrollTop == ‘number‘)) {
20
21       getScrollY = function() {
22           return document.body.scrollTop;
23       }
24
25     } else {
26
27       getScrollY = function() {
28           return NaN;
29       };
30
31     }
32
33     return getScrollY();
34 }

惰性函数定义应用还体现在创建单例上:

 1 unction Universe() {
 2
 3     // 缓存的实例
 4     var instance = this;
 5
 6     // 其它内容
 7     this.start_time = 0;
 8     this.bang = "Big";
 9
10     // 重写构造函数
11     Universe = function () {
12         return instance;
13     };
14 }

当然,像上面这种例子有很多。惰性函数定义,应用场景我们可以总结一下:

1 应用频繁,如果只用一次,是体现不出它的优点出来的,用的次数越多,越能体现这种模式的优势所在;

2 固定不变,一次判定,在固定的应用环境中不会发生改变;

3 复杂的分支判断,没有差异性,不需要应用这种模式;

时间: 2025-01-03 19:19:15

JavaScript惰性函数定义的相关文章

javascript之函数定义

javascript的基础之一 --- function function的定义: 1.直接定义 function test(){ //内容,想要处理的逻辑 } 2.变量式 var demo = function(){ //内容,想要处理的逻辑 }; 3.利用Function var fun = new Function('fun','conlose.log("内容,想要处理的逻辑")'); 1/2两种经常使用,第三种比较少见.第一种函数定义会被提升到最前面,后面一种不可以. test

JavaScript函数定义和调用 变量作用域

本文是笔者在看廖雪峰老师JavaScript教程时的个人总结 JavaScript中函数定义可以是这样的格式 function 函数名(参数) { 函数体 } 也可以是这样的格式 var 函数名 = function (参数) { 函数体 }; 关键字一:arguments 获取全部参数 只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数.arguments类似Array但它不是一个Array.第一个参数是arguments[0]....[n] 关键字二:rest 获取 获取除了已定

和demopu一起学习javascript ( concat函数 )

和demopu一起学习javascript (  concat函数 ) 定义和用法 concat方法可以把两个或者多个数组连接起来,组成一个新的数组. 语法 concat(array1,array2,......,arrayN) 参数 描述 array1 必需.该参数可以是具体的值,也可以是数组对象.可以是任意多个. 例子 1 var arr = ["George","John","Thomas"]; var arr2 = ["Jame

JavaScript高级函数

一.JavaScript惰性函数    function createXHR(){ var xhr = null; try{ //FireFox,Opera 8.0+,Safari,IE7+ xhr = new XMLHttpRequest(); }catch(e){ //Internet Explorer try{ xhr = new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ xhr = new ActiveXObject(&q

JavaScript:函数、标准对象

JavaScript:函数.标准对象 初识函数 函数就和Java中的方法是一样的,说白了,就是一系列语句的集合,我们可以提取出来实现复用! 在JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述abs()函数的定义如下: function指出这是一个函数定义: abs是函数的名称: (x)括号内列出函数的参数,多个参数以,分隔: { ... }之间的代码是函数体,可以

Javascript读书笔记:函数定义和函数调用

定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方式: var add = new Function("m", "n", "alert(m+n);"); Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:&

Javascript我学之二函数定义

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘 函数 几个要点: a).函数是javascript中的一等公民 (重要性) b).函数是一个对象 c).函数定义了一个独立的变量作用域 定义方式 a)命名函数:           除非在另一个函数内部定义,否则,命名函数是全局的. 1 // 全局的命名函数 2 function add(x, y) { 3 return x + y; 4 } 5 console.info(add(100, 200)); //300 b)匿名函数: 匿名函

[转]javascript函数定义表达式和函数声明的区别

在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ return x; } 尽管函数定义表达式和函数声明语句包含相同的函数名,并且都创建了新的函数对象,但是这二者却有区别. 函数声明语句中的函数名是一个变量名,变量指向函数对象. 函数定义表达式和通过var声明变量一样,其函数被提前到了脚本或函数的顶部,因此它在整个脚本和或函数内都是可见的.这样的话

javascript学习3-自定义函数

javascript自定义函数,很简单的小例子. 实现效果:输入两个数和运算符号,根据不同运算符对数据进行计算,返回值 代码: 1 <html> 2 <head> 3 <script type="text/javascript"> 4 var num1=window.prompt('请输入第一个num'); 5 var num2=window.prompt('请输入第二个num'); 6 var operator=window.prompt('请输入