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

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

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

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

 function addEvent (type, element, fun) {
if (element.addEventListener) {
element.addEventListener(type, fun, false);
}
else if(element.attachEvent){
element.attachEvent('on' + type, fun);
}
else{
element['on' + type] = fun;
}
}

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

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

下面我们重写上面的addEvent:

 function addEvent (type, element, fun) {
if (element.addEventListener) {
addEvent = function (type, element, fun) {
element.addEventListener(type, fun, false);
}
}
else if(element.attachEvent){
addEvent = function (type, element, fun) {
element.attachEvent('on' + type, fun);
}
}
else{
addEvent = function (type, element, fun) {
element['on' + type] = fun;
}
}
return addEvent(type, element, fun);
}

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

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

 function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined"){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"]; for (var i=0,len=versions.length; i < len; i++){
try {
var xhr = new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
return xhr;
} catch (ex){
//skip
}
}
} return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}

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

 function createXHR() {
if (typeof XMLHttpRequest != "undefined") {
createXHR = function () {
return new XMLHttpRequest();
}
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
var curxhr;
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"]; for (var i = 0, len = versions.length; i < len; i++) {
try {
var xhr = new ActiveXObject(versions[i]);
curxhr = versions[i];
createXHR = function () {
return new ActiveXObject(curxhr);
}
return xhr;
} catch (ex) {
//skip
}
}
} else {
throw new Error("No XHR object available.");
}
}

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

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

 var getScrollY = function() {

     if (typeof window.pageYOffset == 'number') {

         getScrollY = function() {
return window.pageYOffset;
}; } else if ((typeof document.compatMode == 'string') &&
(document.compatMode.indexOf('CSS') >= 0) &&
(document.documentElement) &&
(typeof document.documentElement.scrollTop == 'number')) { getScrollY = function() {
return document.documentElement.scrollTop;
}; } else if ((document.body) &&
(typeof document.body.scrollTop == 'number')) { getScrollY = function() {
return document.body.scrollTop;
} } else { getScrollY = function() {
return NaN;
}; } return getScrollY();
}

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

 unction Universe() {

     // 缓存的实例
var instance = this; // 其它内容
this.start_time = 0;
this.bang = "Big"; // 重写构造函数
Universe = function () {
return instance;
};
}

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

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

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

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

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

  1. javascript 回调函数定义 模板

    函数定义: function callfun(in_param,callback) { console.log(in_param); var out_param='bbbbb'; return (ty ...

  2. javascript惰性函数

    惰性函数:所谓惰性函数就是创建了一个新函数并且将其分配给保存了另外函数的同一个变量,就以一个新函数覆盖了旧函数.某种程度上,回收了旧函数指针以指向一个新函数. 板栗: var scareMe = fu ...

  3. javascript . 03 函数定义、函数参数(形参、实参)、函数的返回值、冒泡函数、函数的加载、局部变量与全局变量、隐式全局变量、JS预解析、是否是质数、斐波那契数列

    1.1 知识点 函数:就是可以重复执行的代码块 2.  组成:参数,功能,返回值 为什么要用函数,因为一部分代码使用次数会很多,所以封装起来, 需要的时候调用 函数不调用,自己不会执行 同名函数会覆盖 ...

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

     本文是笔者在看廖雪峰老师JavaScript教程时的个人总结   JavaScript中函数定义可以是这样的格式 function 函数名(参数) {     函数体 } 也可以是这样的格式     ...

  5. 【JavaScript】函数

    No1: 定义函数 function abs(x) { if (x >= 0) { return x; } else { return -x; } } var abs = function (x ...

  6. JavaScript之惰性函数

    前不久看到javascript的性能优化的这里,有关惰性函数 假如同一个函数有许多判断来检测函数,而我们每一次调用,都会判断检测函数 例如: function addEvent (type, elem ...

  7. 深入理解javascript函数定义与函数作用域

    最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把思路整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径 ...

  8. JavaScript要点 (五) 函数定义

    JavaScript 使用关键字 function 定义函数. 函数可以通过声明定义,也可以是一个表达式. 函数声明分号是用来分隔可执行JavaScript语句. 由于函数声明不是一个可执行语句,所以 ...

  9. javascript函数定义表达式和函数声明的区别

    在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ ...

随机推荐

  1. JavaScript 简单吗

    英文:Aurélien Hervé  译文:众成翻译/msmailcode 这里有一些 Javascript初学者应该知道的技巧和陷阱.如果你已经是专家了,顺便温习一下. Javascript也只不过 ...

  2. java 多线程总结篇1之——基本概念

    1.什么是线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,每个线程 ...

  3. xcode7 创建pch文件

    1.打开xcode 7.2 项目,在屏幕顶端的工具栏,选择File>New>File..>iOS>Other>PCH File,点击"next"下一步 ...

  4. Effective STL 学习笔记: Thread Safety and STL Container

    Table of Contents 1. STL, Thread and SGI 2. STL and Lock 2.1. RAII 2.2. Use Lock in STL 1 STL, Threa ...

  5. Python装饰器讲解

    Python装饰器讲解 定义:本质是函数,就是为其他函数添加附加功能.原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 import time def timmer(func ...

  6. JavaScript中构造函数

    构造函数:函数的另一种执行方法,执行后创建对象,并创建原型对象. 原型链:对象访问构造函数的指针. Function函数:函数对象. Object函数:所有创建对象的祖辈对象,也是由Function对 ...

  7. hiho 1227 找到一个恰好包含n个点的圆 (2015北京网赛 A题)

    平面上有m个点,要从这m个点当中找出n个点,使得包含这n个点的圆的半径(圆心为n个点当中的某一点且半径为整数)最小,同时保证圆周上没有点. n > m 时要输出-1 样例输入43 2 0 0 1 ...

  8. 为django平台生成模拟用户,建立用户组,并将用户加入组

    书接上篇BLOG. 当我们可以用manage.py自定义命令来生成模拟数据时, 我们面对的就是如何操作ORM的问题了. 这两天,我为我们的内部系统的所有数据表,都生成了模拟数据. 有几个心得,记录于此 ...

  9. Monaco Editor 使用入门

    以前项目是用ace编辑器的,但是总有些不敬人意的地方.前端事件看见的VS Code编辑器Monaco Editor准备更换下,下面介绍一些使用中遇到的一点问题.代码提示 1.项目引用 import * ...

  10. USACO 6.5 Closed Fences

    Closed Fences A closed fence in the plane is a set of non-crossing, connected line segments with N c ...