- 浏览: 89037 次
文章分类
最新评论
第一章代码重用和优化
一、有关继承的一些笔记
1.在JS中,类的继承是可以通过prototype(原型方式),call等方式实现的,但是这种方式需要使用new来创建类,如果我们忘记使用类,那么this,返回值等问题就会出现,所以,需要考虑使用模块模式的方法,
var serialMaker=function(){
//返回一个用来产生唯一字符串的对象。
//唯一字符串由两部分组成:前缀+序列号
//该对象包含一个设置前缀的方法,一个设置序列号的方法
//和一个产生唯一字符串的gensym方法
var prefix='';
var seq=0;
return {
setPrefix:function(p){
prefix=String(p);
},
setSeq:function(s){
seq=s;
},
gensym:function(){
var result=prefix+seq;
seq+=1;//JS解释器并不是把seq+=1视作未声明的赋值语句,因为seq已经声明过了,内部函数可以访问外部函数的变量。
return result;
}
};
};
当然也可以使用JS语言精粹第五章提到的
var mammal=function(spec){
var that={};//第1步
that.get_name=function(){//3
return spec.name;
};
that.says=function(){
return spec.saying||’’;
};
return that;//4
};
这个函数化的方法,相比与模块话的方法,函数化的方法,可以更好的提供封装
比如下面
var pet = function (name,legs){
var that = {
name:name,
getDetails:function(){
return that.name+'has'+legs+'legs';
}
};
return that;
};
var cat = function(name){
var that = pet(name,4);
that.action = function(){
return 'Catch a bird';
};
return that;
};
var petCat2 = cat('Felix');
details = petCat2.getDetails();
action = petCat2.action();
petCat2.name = 'test';
petCat2.legs = 7;
details = petCat2.getDetails();
/*这里无法访问legs属性,因为legs属性存在于内部函数getDetails中,只有通过内部函数getDetails去进行访问,因为JS有函数级作用域。所以说这种方式封装的很漂亮。
*/
但是要注意使用这种方式不及原形继承的一点就是原形继承不管它被继承了多少次,对象的属性和方法只被保存一次。函数继承则相反,每个实例都会创建重复的属性和方法,如果你要创建许多(如上千个)大对象的实例,内存消耗可能会成为一个问题,不过这个问题很容易解决,可以将较大的属性或方法保存在一个对象中,并将其作为参数传给构造函数,这样所有实例就可以共同使用一个对象资源,而不是创建自己的版本
1.2优化什么,何时优化
1.这里要注意一件事情,之前我们学习了很多优化方式,但是要注意,一般来说,20%的代码将占用80%的cpu周期,所以,我们应该集中优化这20%,而忽略其他部分,这样可以保持很好的可读性。bug也会更少。
1.3自定义代码性能测试
1.一般使用基本的运行时间作为性能的测试评判标准,如
var startTime = new Date()..getTime();
//run some test code here
var timeElapsed = new Date().getTime()-startTime;
但是这种方式可能因为垃圾回收,系统上运行的其他进程所影响,所以,我们可以考虑使用在相同时间内,看谁的循环次数多来评判。
var startTime = new Date()..getTime();
for(var iters = 0 ; timeElapsed<1000 ;iters++){
//run some test code here
timeElapsed = new Date().getTime()-startTime;
}
//iters = number of iterations achieved in 1000 millseconds
使用这种方式。通过循环次数的多少来判断性能。
1.4优化Javascript
1.4.1查找表
对于一些高开销用的计算,我们可以事先将结果运算好,然后放在一个数组,也就是查找表中。
比如,对于Math.sin()方法,可以使用这样的方式来减少运算开销。
var fastSin = function(steps){
var table = [],
ang = 0,
angStep =(Math.PI * 2) / steps;
do{
table.push(Math.sin(ang));
ang+=angStep;
}while(ang<Math.PI * 2);
return table;
};
1.4.2位操作、整数、二进制数
1.JavaScript位操作,
与操作& 也可以达到类似取余运算符%的效果,也就是返回除法后的余数,下面的代码将保证变量value总是在0到7之间,
value&=7;//Equivalent to value % 8;
不过这种等价只有在&后面的值是2的幂-1时才成立。也就是在对2的幂取余的运算成立。
位异或,如果两个操作数的某一位只有一个为1,将对应结果位设1。这很方便地用于切换变量。
toggle^=1
当然这里的toggle 原来的值是1或0,那么每次执行toggle^=1 toggle的值将在1和0之间转换。
位非:对所有位进行取反,例如1110011将变成00011000,如果操作数是有符号整数,则~操作符等于取负减1,前面提到过,补码中取负对应各位取反加1。
位左移,对x的二进制向左移numBits位,所有位向左移,最左的位丢失,0填补最右的位。这等价于无符号整数的乘法 x*2^numBits
y = 5<<1 // 等价于Math.floor(5*2^1)
y = 5 <<2//等价于Math.floor(5*2^2)也就是5*4
算术位右移:对x的二进制向右移numBits位,除了(最左)符号位,所有位向右移,最右位丢失,这相当于有符号整数除法 x/2^numBits
例如 y =10>>1;//y=5等价于Math.floor(5/(2^1))
y =10>>2//y=2等价于Math.floor(5/(2^2))
y =10>>3//y=1等价于Math.floor(5/(2^3))
注意上面的这个位左移和算术位右移,和对应的乘法运算和除法运算。相比就没有性能提升。但是下面这个代码虽然看似毫无用处。但是在性能方面有着提升
x=y>>0;
这个使的JS调用其内部的整数转换函数,剔除数字的小数部分,这实际上是一个快速的Math.floor()函数。在ie8,chrome,safari中都有性能的提升。
逻辑位右移x>>>y:类似>>,但符号位不保留而填补为0,对正数来说,这个>没有区别,对负数来说,逻辑位右移的结果将变为正数。
3.循环展开,麻烦的真相
达夫设备指的是由Tom Duff在1983年开发的一种循环展开的C语言优化技术,循环展开是汇编语言中常用的技术,细小的优化就可以在内存复制等领域发挥作用。具有优化功能的编译器也可能进行自动的循环展开。
但是这种方法比较适合于循环迭代次数很多,并且循环体开销(循环的操作)比循环开销要大的多。这个时候使用这个效果才好,一般来说,我们需要在实际的背景下测试这种优化技术是否值得我们使用。
1.5优化jQuery与DOM交互
1.5.1优化CSS格式变化
比如 $('#element1');.css('color','#f00');
这个语句首先,调用jQuery并让它在DOM中搜索一个id 为element1的元素,除了搜索本身之外,他还涉及进行正则表达式测试来决定需要搜索的类型。
第二步,返回找到的元素列表,一个特殊的jQuery数组对象。
第三步,调用jQuery的css函数,这会进行不同的检查,如决定读写,是否传入一个字符串参数,对象或者更多。最后更新元素样式本身。
重复运用上面$('#element1');.css('color','#f00');
$('#element1');.css('color','#0f0');
$('#element1');.css('color','#00f');
会十分没有效率
针对上面这三个步骤,有如下的优化方法,
针对第一个步骤,尝试指定jQuery的搜索范围,jQuery默认从document根或是DOM层次的最上层开始搜索,这完全没有必要,我们可以指定一个搜索范围,比如说
$alien = $('.alien',container);这个container是灵活的,可以是另一个jQuery对象或是css选择器。
$alien = $('.alien',$container);
$alien = $('.alien','#container');
当然要确保搜索环境不比搜索元素本身慢,
针对第二步,我们可以使用一个局部变量存储中间结果
var $elem = $('#element1');.css('color','#f00');//这个$只是代表他是一个jQuery对象。可以使用这种方式!表明这个变量是jQuery对象。
$elem.css('color','#0f0');
$elem.css('color','#00f');
针对第三步,使用
var elemStyle = $('#element1')[0].style
elemStyle.color= '';
另外直接操作元素属性本身比使用jQuery要快,比如jQuery.html() 方法要比直接使用一个元素的innerHTML慢许多。
一、有关继承的一些笔记
1.在JS中,类的继承是可以通过prototype(原型方式),call等方式实现的,但是这种方式需要使用new来创建类,如果我们忘记使用类,那么this,返回值等问题就会出现,所以,需要考虑使用模块模式的方法,
var serialMaker=function(){
//返回一个用来产生唯一字符串的对象。
//唯一字符串由两部分组成:前缀+序列号
//该对象包含一个设置前缀的方法,一个设置序列号的方法
//和一个产生唯一字符串的gensym方法
var prefix='';
var seq=0;
return {
setPrefix:function(p){
prefix=String(p);
},
setSeq:function(s){
seq=s;
},
gensym:function(){
var result=prefix+seq;
seq+=1;//JS解释器并不是把seq+=1视作未声明的赋值语句,因为seq已经声明过了,内部函数可以访问外部函数的变量。
return result;
}
};
};
当然也可以使用JS语言精粹第五章提到的
var mammal=function(spec){
var that={};//第1步
that.get_name=function(){//3
return spec.name;
};
that.says=function(){
return spec.saying||’’;
};
return that;//4
};
这个函数化的方法,相比与模块话的方法,函数化的方法,可以更好的提供封装
比如下面
var pet = function (name,legs){
var that = {
name:name,
getDetails:function(){
return that.name+'has'+legs+'legs';
}
};
return that;
};
var cat = function(name){
var that = pet(name,4);
that.action = function(){
return 'Catch a bird';
};
return that;
};
var petCat2 = cat('Felix');
details = petCat2.getDetails();
action = petCat2.action();
petCat2.name = 'test';
petCat2.legs = 7;
details = petCat2.getDetails();
/*这里无法访问legs属性,因为legs属性存在于内部函数getDetails中,只有通过内部函数getDetails去进行访问,因为JS有函数级作用域。所以说这种方式封装的很漂亮。
*/
但是要注意使用这种方式不及原形继承的一点就是原形继承不管它被继承了多少次,对象的属性和方法只被保存一次。函数继承则相反,每个实例都会创建重复的属性和方法,如果你要创建许多(如上千个)大对象的实例,内存消耗可能会成为一个问题,不过这个问题很容易解决,可以将较大的属性或方法保存在一个对象中,并将其作为参数传给构造函数,这样所有实例就可以共同使用一个对象资源,而不是创建自己的版本
1.2优化什么,何时优化
1.这里要注意一件事情,之前我们学习了很多优化方式,但是要注意,一般来说,20%的代码将占用80%的cpu周期,所以,我们应该集中优化这20%,而忽略其他部分,这样可以保持很好的可读性。bug也会更少。
1.3自定义代码性能测试
1.一般使用基本的运行时间作为性能的测试评判标准,如
var startTime = new Date()..getTime();
//run some test code here
var timeElapsed = new Date().getTime()-startTime;
但是这种方式可能因为垃圾回收,系统上运行的其他进程所影响,所以,我们可以考虑使用在相同时间内,看谁的循环次数多来评判。
var startTime = new Date()..getTime();
for(var iters = 0 ; timeElapsed<1000 ;iters++){
//run some test code here
timeElapsed = new Date().getTime()-startTime;
}
//iters = number of iterations achieved in 1000 millseconds
使用这种方式。通过循环次数的多少来判断性能。
1.4优化Javascript
1.4.1查找表
对于一些高开销用的计算,我们可以事先将结果运算好,然后放在一个数组,也就是查找表中。
比如,对于Math.sin()方法,可以使用这样的方式来减少运算开销。
var fastSin = function(steps){
var table = [],
ang = 0,
angStep =(Math.PI * 2) / steps;
do{
table.push(Math.sin(ang));
ang+=angStep;
}while(ang<Math.PI * 2);
return table;
};
1.4.2位操作、整数、二进制数
1.JavaScript位操作,
与操作& 也可以达到类似取余运算符%的效果,也就是返回除法后的余数,下面的代码将保证变量value总是在0到7之间,
value&=7;//Equivalent to value % 8;
不过这种等价只有在&后面的值是2的幂-1时才成立。也就是在对2的幂取余的运算成立。
位异或,如果两个操作数的某一位只有一个为1,将对应结果位设1。这很方便地用于切换变量。
toggle^=1
当然这里的toggle 原来的值是1或0,那么每次执行toggle^=1 toggle的值将在1和0之间转换。
位非:对所有位进行取反,例如1110011将变成00011000,如果操作数是有符号整数,则~操作符等于取负减1,前面提到过,补码中取负对应各位取反加1。
位左移,对x的二进制向左移numBits位,所有位向左移,最左的位丢失,0填补最右的位。这等价于无符号整数的乘法 x*2^numBits
y = 5<<1 // 等价于Math.floor(5*2^1)
y = 5 <<2//等价于Math.floor(5*2^2)也就是5*4
算术位右移:对x的二进制向右移numBits位,除了(最左)符号位,所有位向右移,最右位丢失,这相当于有符号整数除法 x/2^numBits
例如 y =10>>1;//y=5等价于Math.floor(5/(2^1))
y =10>>2//y=2等价于Math.floor(5/(2^2))
y =10>>3//y=1等价于Math.floor(5/(2^3))
注意上面的这个位左移和算术位右移,和对应的乘法运算和除法运算。相比就没有性能提升。但是下面这个代码虽然看似毫无用处。但是在性能方面有着提升
x=y>>0;
这个使的JS调用其内部的整数转换函数,剔除数字的小数部分,这实际上是一个快速的Math.floor()函数。在ie8,chrome,safari中都有性能的提升。
逻辑位右移x>>>y:类似>>,但符号位不保留而填补为0,对正数来说,这个>没有区别,对负数来说,逻辑位右移的结果将变为正数。
3.循环展开,麻烦的真相
达夫设备指的是由Tom Duff在1983年开发的一种循环展开的C语言优化技术,循环展开是汇编语言中常用的技术,细小的优化就可以在内存复制等领域发挥作用。具有优化功能的编译器也可能进行自动的循环展开。
但是这种方法比较适合于循环迭代次数很多,并且循环体开销(循环的操作)比循环开销要大的多。这个时候使用这个效果才好,一般来说,我们需要在实际的背景下测试这种优化技术是否值得我们使用。
1.5优化jQuery与DOM交互
1.5.1优化CSS格式变化
比如 $('#element1');.css('color','#f00');
这个语句首先,调用jQuery并让它在DOM中搜索一个id 为element1的元素,除了搜索本身之外,他还涉及进行正则表达式测试来决定需要搜索的类型。
第二步,返回找到的元素列表,一个特殊的jQuery数组对象。
第三步,调用jQuery的css函数,这会进行不同的检查,如决定读写,是否传入一个字符串参数,对象或者更多。最后更新元素样式本身。
重复运用上面$('#element1');.css('color','#f00');
$('#element1');.css('color','#0f0');
$('#element1');.css('color','#00f');
会十分没有效率
针对上面这三个步骤,有如下的优化方法,
针对第一个步骤,尝试指定jQuery的搜索范围,jQuery默认从document根或是DOM层次的最上层开始搜索,这完全没有必要,我们可以指定一个搜索范围,比如说
$alien = $('.alien',container);这个container是灵活的,可以是另一个jQuery对象或是css选择器。
$alien = $('.alien',$container);
$alien = $('.alien','#container');
当然要确保搜索环境不比搜索元素本身慢,
针对第二步,我们可以使用一个局部变量存储中间结果
var $elem = $('#element1');.css('color','#f00');//这个$只是代表他是一个jQuery对象。可以使用这种方式!表明这个变量是jQuery对象。
$elem.css('color','#0f0');
$elem.css('color','#00f');
针对第三步,使用
var elemStyle = $('#element1')[0].style
elemStyle.color= '';
另外直接操作元素属性本身比使用jQuery要快,比如jQuery.html() 方法要比直接使用一个元素的innerHTML慢许多。
发表评论
-
高性能网站建设指南规则8使用外部Javascript和CSS
2013-01-22 13:13 842HTML文档,至少是那些包含动态内容的HTML文档。通常不会被 ... -
理解JS call apply
2012-11-06 14:35 893call([thisObj[,arg1[, arg2[, [, ... -
浅析JS全局变量与局部变量 执行环境 作用域链 JS解释器执行过程
2012-11-05 16:04 1457参考http://hi.baidu.com/cjry_ ... -
javascript encodeURI和encodeURIComponent的比较
2012-10-30 16:38 887encodeURI 和 encodeURIComponent都 ... -
JS跨域的理解
2012-10-30 15:08 920首先我们要理解什么是JS跨域的由来! 我是这样理解的,因为HT ... -
jquery.history简单理解
2012-10-30 14:34 1842jquery.history的简单理解 原理是利用形如 ma ... -
js事件捕获和事件冒泡
2012-10-28 10:48 973] Netscape 定义了事件捕获,先是最顶级的元素(doc ... -
jQuery对象包含的内容及两种扩展方式
2012-10-24 18:50 770jQuery对象包含的内容及 ... -
早绑定和晚绑定
2012-10-17 11:13 1034引用早绑定(early binding)是指在实例化对象之前定 ... -
AJAX和JSON的一些理解
2012-09-22 20:09 757正在学习JSON和AJAX,记录下自己的理解 AJAX 什么是 ... -
关于火狐浏览器页面无法获得焦点的学习笔记
2012-07-17 19:13 1067发现类似:window.setTimeout(function ... -
JS应用对于IE和Firefox的区别
2012-07-17 18:51 01.FireFox没有window.event而且没有srcE ... -
javascript中arguments、callee、caller用法学习笔记
2012-07-16 10:22 1028首先是caller和callee的区别。注意caller和ca ... -
【转】event对象、srcElement、offsetX 在 firefox中的解决方案
2012-07-16 09:13 1114问题一:在IE中event作为 ...
相关推荐
本篇将围绕“Java+JDK6学习笔记”展开,探讨在JDK6环境下Java编程的核心知识点。 1. **JDK6概述**:JDK6是Oracle公司于2006年发布的Java平台标准版(Java SE)的一个重要版本,它的全称是Java SE 6,带来了许多新...
### 韩顺平编写的Java学习笔记概览 #### Java平台分类与运行机制 - **J2SE(Java 2 Platform, Standard Edition)**: 标准版Java开发平台,适用于桌面应用程序开发。 - **J2EE(Java 2 Platform, Enterprise ...
【Java学习笔记、SSH学习笔记】是一份涵盖了Java Web开发中的关键技术和框架的资源集合,主要涉及了JSP(JavaServer Pages)、JSTL(JavaServer Pages Standard Tag Library)、EL(Expression Language)以及SSH...
Dojo 是一个功能丰富的 JavaScript 库,它提供了一系列模块化、面向对象的工具,用于构建高性能的 Web 应用程序。在 Dojo 中,模块和包...通过深入学习和理解这些模块和包,开发者可以构建高效、健壮的 Web 应用程序。
这篇笔记主要涵盖了JavaScript的起源以及浏览器的发展历史,同时深入解析了JavaScript的基本特性和工作原理。 首先,我们来看看浏览器的历史。JavaScript的发展与浏览器的演进紧密相关。蒂姆·伯纳斯-李在1990年...
JavaSE6学习笔记是针对Java初学者和进阶者的一份宝贵资料,由知名讲师李兴华的培训课堂笔记汇编而成。这份笔记全面、详细地涵盖了Java SE 6版本的核心概念和技术,对于理解Java编程语言的基础以及进阶特性具有重要...
Flex ActionScript 学习笔记是关于使用Adobe Flex技术并结合ActionScript 3.0进行开发的知识总结。ActionScript 3.0是随着Flash CS3一起推出的一种强大的编程语言,相较于之前的ActionScript版本,它有着显著的提升...
在Android平台上,Cocos2d-x是一个非常流行的分支,它用C++编写,并且支持多种编程语言,包括Lua和JavaScript。这个“Cocos2d-android-1学习笔记”正是针对初学者或者正在深入学习Cocos2d-x在Android平台应用的...
此外,图形动画和效果的章节会介绍如何利用Qt5的图形系统来制作吸引人的视觉效果,而粒子系统和canvas章节则涉及到更高级的图形编程技巧,可用于创建复杂的动画和游戏。 多媒体应用的开发将涵盖音频和视频的处理,...
压缩包中的“QT5相关资料”可能包含了QT5的官方文档、教程、示例代码和学习笔记。官方文档详细介绍了每个类和函数的用法,是学习QT5的重要参考资料。教程和示例代码可以帮助初学者快速上手,理解QT5的基本概念和实践...
JavaScript作为客户端编程的主要语言,是实现交互性和动态功能的关键。理解变量、数据类型、函数、DOM操作等基础知识是进阶到AJAX、jQuery、Vue.js、React.js等前端框架的基石。这些框架可以简化代码,提高开发效率...
《林信良的JDK6学习笔记源代码》是一份珍贵的学习资源,它包含了林信良在其著作《JDK6学习笔记》中所使用的全部源代码。这份源代码集可以帮助读者深入理解书中讲解的Java编程概念和技术,尤其对于正在学习JDK6版本的...
本学习笔记将深入探讨Java JDK 6中的关键知识点,帮助初学者和有经验的开发者更好地理解和应用这个版本的Java。 一、Java基础 Java是一种面向对象的编程语言,其特点包括跨平台性、垃圾回收机制和自动内存管理。在...
### Dojo学习笔记详解 #### 一、Dojo基本概念 Dojo是一个强大的JavaScript库,旨在简化复杂的Web应用程序开发过程。它由三个主要部分组成:`dojo`、`dijit`和`dojox`。 1. **Dojo基础**: - **概述**:Dojo的...
这份"Java JDK 6学习笔记——ppt简体版"很可能是对这一版本特性和使用方法的详细讲解,旨在帮助初学者和有经验的开发者深入理解JDK 6的核心功能和改进。 JDK(Java Development Kit)是Java编程语言的软件开发工具...
### Java 学习笔记知识点梳理 #### Java 平台概述 - **J2SE(Java 2 Platform Standard Edition)**: 标准版平台,适用于桌面应用程序的开发。 - **J2EE(Java 2 Platform Enterprise Edition)**: 企业版平台,...
在描述中提到了使用 .NET 2003、VML 和 JavaScript 创建Web图形化流程图的技术。VML 是一种矢量图形语言,它允许在IE浏览器中绘制复杂的图形并实现动态效果。在.NET 2003环境下,通过定义命名空间,可以利用VML的...