函数是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. 二、springboot配置

    一.启动类 在包根目录下添加启动类,必须包含main方法,再添加Spring Boot启动方法: SpringApplication.run(SampleController.class, args) ...

  2. asp.net mvc 本地化 默认的错误提示

    System.ComponentModel.DataAnnotations 给我们提供了一些特性来直接对model的属性进行验证和约束, 同时也提供了 ErrorMessageResourceName ...

  3. 【Android开发日记】之入门篇(六)——Android四大组件之Broadcast Receiver

    广播接受者是作为系统的监听者存在着的,它可以监听系统或系统中其他应用发生的事件来做出响应.如设备开机时,应用要检查数据的变化状况,此时就可以通过广播来把消息通知给用户.又如网络状态改变时,电量变化时都 ...

  4. elasticsearch5.5

    1.不能以root用户运行 groupadd es          #增加es组 useradd es -g es -p pwd          #增加es用户并附加到es组 chown -R e ...

  5. 【笔记】jQuery插件开发指南

    原文链接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html (有部分增删和修改) jQuery插件开发模式 软件开发过程中是需要一定 ...

  6. INSTEAD OF与AFTER触发器

    INSTEAD OF 触发器 AFTER 触发器(也叫“FOR”触发器)会在触发 insert.update 或是delect 动作之后执行.例如,一个 Employees 表上的 AFTER 触发器 ...

  7. MySQL学习笔记:生成时间维度表

    # ---- 对应时间戳怎么生成的? ---- /*TIME_CD TIME_CD1000000 000005000001 000005000002 000005000003 000005000004 ...

  8. 开源的python机器学习模块

    1. Scikit-learn Scikit-learn 是基于Scipy为机器学习建造的的一个Python模块,他的特色就是多样化的分类,回归和聚类的算法包括支持向量机,逻辑回归,朴素贝叶斯分类器, ...

  9. HBase(九)HBase表以及Rowkey的设计

    一 命名空间 1 命名空间的结构 1) Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定, 则在 default 默认的命名空间中. 2) RegionServer g ...

  10. thinkphp3.2开启静态缓存与缓存规则设置

    网站的静态缓存对大访问量有很好的缓解作用,尤其对网站的大并发,可有效的缓解数据库的压力.在thinkphp中实现静态缓存很简单,thinkphp都已经封装好了直接调用即可. 静态缓存   首先设置 H ...