JavaScript高级程序设计学习笔记--高级技巧
惰性载入函数
因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中,看看下面来自上一章的createXHR()函数。
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"],
i, len; for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
} return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
每次调用createXHR()的时候,它都要对浏览器所支持的能力仔细检查。每次调用该函数都是这样,即使每次调用时分支的结果不变:浏览器内置XHR,那么它就一直支持了,那么
这种测试就变得没必要了。即使只有一个If语句的代码,也肯定要比没有If语句慢,所以如果If语句不必要每次执行,那么代码可以运行地更快一些。解决方案就是称之为惰性载入
的技巧。
惰性载入表示函数执行的分支仅会发生一次。有两种实现惰性载入的方式。第一种就是在函数被调用时再处理函数,在第一次调用的过程中,该函数会被覆盖为另外一个按合适方式
执行的函数,这样第二次再调用的时候就不用再经过执行的分支了。
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
createXHR = function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
createXHR = function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len; for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
} catch (ex){
//skip
}
}
} return new ActiveXObject(arguments.callee.activeXString);
};
} else {
createXHR = function(){
throw new Error("No XHR object available.");
};
} return createXHR();
} var xhr1 = createXHR();
var xhr2 = createXHR();
第二种实现惰性载入的方式是在声明函数时就指定适当的函数。这样,第一次调用函数时就不会损失性能了,而在代码首次加载时会损失一点性能。
var createXHR = (function(){
if (typeof XMLHttpRequest != "undefined"){
return function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
return function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len; for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
} return new ActiveXObject(arguments.callee.activeXString);
};
} else {
return function(){
throw new Error("No XHR object available.");
};
}
})(); var xhr1 = createXHR();
var xhr2 = createXHR();
重复的定时器
setTimeout(function(){ var div = document.getElementById("myDiv"),
left = parseInt(div.style.left) + 5;
div.style.left = left + "px"; if (left < 200){
setTimeout(arguments.callee, 50);
} }, 50);
函数节流
函数节流背后的基本思想是指,某些代码不可以在没有间断的情况下连续重复执行。第一次调用函数创建一个定时器,在指定的时间间隔之后运动代码。当第二次调用该函数时,
它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。
目的是只有在执行函数请求停止了一段时间 之后才执行。以下是该模式的基本形式:
var processor={
timeoutId:null,
//实际进行处理的方法
performProcessing:function(){
//实际执行的代码
},
process:function(){
clearTimeout(this.timeoutId); var that=this;
this.timeoutId=setTimeout(function(){
that.performProcessing();
},100
}
};
当调用了process(),第一步是清除存好的timeoutId,来阻止之前的调用被执行。然后,创建一个新定时器调用performProcessing()。由于setTimeout()中用到的函数环境总是
window,所以有必要保存this的引用以方便以后使用。
时间间隔设为了100ms,这表示最后一次调用process()之后至少100ms后才会调用performProcessing()。所以如果100ms之间内调用了process()共20次,performanceProcessing()
仍只会被调用一次。
这个模式可以用throttle()函数来简化,这个函数可以自动进行定时器的设置和消除,如下例所示:
function throttle(method, scope) {
clearTimeout(method.tId);
method.tId= setTimeout(function(){
method.call(scope);
}, 100);
} function resizeDiv(){
var div = document.getElementById("myDiv");
div.style.height = div.offsetWidth + "px";
} window.onresize = function(){
throttle(resizeDiv);
};
JavaScript高级程序设计学习笔记--高级技巧的更多相关文章
- JavaScript高级程序设计---学习笔记(一)
今天,2017.3.17开始利用课余时间仔细学习<JavaScript高级程序设计>,将需要掌握的知识点记录下来,争取把书里的所有代码敲一遍并掌握. 1.标识符命名最好是第一个字母小写,剩 ...
- javascript高级程序设计学习笔记
javascript高级程序设计,当枕头书已经好久了~zz 现在觉得自己在js的开发上遇到了一些瓶颈,归根究底还是基础太薄弱,所以重新刷一遍js高程希望有更新的认识. 一.javascript简介 ...
- javascript 高级程序设计 学习笔记
<!--<script> // 异步请求封装 IE6即以上浏览器 // ajax(url,fnSucc,selectID,fnFaild) //url 请求地址 //fnSucc 异 ...
- JavaScript高级程序设计---学习笔记(二)
面向对象程序设计1.属性类型.定义多属性.读取属性特性对象的属性在创建时都带有一些特征值,JavaScript通过这些特征值来定义它们的行为.这些特性是为了实现JavaScript引擎用的,因此不能直 ...
- JavaScript高级程序设计学习笔记--面向对象的程序设计(二)-- 继承
相关文章: 面向对象的程序设计(一) — 创建对象 http://www.cnblogs.com/blackwood/archive/2013/04/24/3039523.html 继承 继承是OO语 ...
- JavaScript高级程序设计学习笔记第一章
作为学习javascript的小白,为了督促自己读书,写下自己在读书时的提炼的关键点. 第一章: 1.JavaScript简史:Netscape Navigator中的JavaScript与Inter ...
- JavaScript高级程序设计学习笔记之事件
1.事件流 事件流描述的是从页面中接收事件的顺序. 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播 ...
- 事件流之事件冒泡与事件捕获<JavaScript高级程序设计>学习笔记
1.事件流 浏览器开发团队遇到一个很有意思问题:页面的那一部分会拥有特定的事件? 对于理解这个问题您可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上 ...
- JavaScript高级程序设计学习笔记--错误处理与调试
try-catch语句 只要代码中包含finally子句,则无论try或catch语句块中包含什么代码--甚至return语句,都不会阻止finally子句的执行,来看下面这个函数: function ...
随机推荐
- docker搭建ros-indigo-arm交叉编译环境
ROS运行环境:ARM ubuntu14.04 + ROS indigo在arm环境下编译ros应用程序,速度极慢,无法忍受,尝试在x86机器上搭建docker+ros交叉编译环境. 交叉编译环境的搭 ...
- 一道有意思的笔试题引发的对于new操作符的思考
楼主比较喜欢看一些很短但很有意思的题目,无意间又瞥到了一题,大家不妨可以一试.(原题链接猛戳这里) function Fn1() { this.name = 'peter'; return { nam ...
- mysql Workbench 执行删除命令
SET SQL_SAFE_UPDATES = 0;delete from table1; SET SQL_SAFE_UPDATES = 1;
- VUE --- 给页面加点网络动态数据
这时候的页面都是静态的(数据在写程序的时候已经固定了不能修改),而每个应用基本上都会请求外部数据以动态改变页面内容.对应有一个库叫 vue-resource 帮我们解决这个问题. 使用命令行安装 cn ...
- 移动端meta
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scal ...
- VMware安装ubuntu虚拟机
创建虚拟机完成. 安装操作系统. 中文版界面: 中文版界面: 稍等在重启 重新启动虚拟机. 安装VMtools 双击该图标 安装完成,重新启动系统. 如果在安装的时候,主机名没有修改 看着太长 如何修 ...
- Zabbix监控nginx status
nginx开启status ./configure --with-http_stub_status_module nginx.conflocation /statusx35 { stub_status ...
- 怪物AI之发现玩家(视觉范围发现系列)
在网上找到一些资料参考,然后写写自己的想法. 这里感谢MOMO等大神. 我们用玩家检测怪物的方法来测,这样比较试用与弱联网游戏,每次在同步玩家的时候来判断玩家与怪物的位置. 这里给出两个处理方式: 1 ...
- 团队博客作业- Week3
成员介绍 韩青长 测试 我是韩青长,技术小白,抱着对软工的好奇和对未来工作的憧憬选了这门课.暂时选择了测试的工作,也对开发和UI有一定兴趣.从前上帝创造了我们,现在轮到我们来创造自己的软件了~ 陈彦 ...
- js 时间相关函数
实例: <!doctype html> <html> <head> <meta charset="utf-8"> <title ...