随着网络的发展,网络的速度和机器的速度,越来越多的网站都使用富客户端技术,Ajax和现在最流行的是way.javascript是一种解释型语言,所以它不能达到C或java等水平,可以做为客户的东西,可以提高自己的表现,我想谈谈自己的经验,很多测试我给Javascript完成的基础上,希望能帮助你提高你的Javascript脚本的性能。

前言

一直在学习javascript,见过快速开发jQuery内核的解释与实践

因为想让自己有一个提升,不到一个更广阔的世界,找到一个属于自己的家,所以平时积累有意无意的一些常识的jquerry的使用,特别是对这一要求,总是认为没有更好的方式来实现。

以下是我总结过的一些小技巧,仅供参考(我将从一个普通的标题开始,然后用一个小单词来解释这个意义,然后最后用一个演示来简化闫明)。

避免全局查找

在函数中,全局对象作为局部变量存储,以减少全局查找,因为访问局部变量比访问全局变量要快。


函数搜索(){
当我想使用当前页地址和主机名时
警报(window.location.href +窗口位置。主持人);
}
最好的方法如下:第一个是用一个简单的变量来支撑
函数搜索(){
VaR的位置= window.location;
警报(location.href +位置。主持人);
}


定时器



如果你的目标是在运行代码,你不应该使用setTimeout而setInterval,因为setTimeout启动定时器每隔一段时间,而setInterval启动开始计时。


无功timeouttimes = 0;
函数超时(){
timeouttimes + +;
如果(timeouttimes<10){
setTimeout(超时,10);
}
}
超时();
可以替换:
无功intervaltimes = 0;
函数间隔(){
intervaltimes + +;
如果(intervaltimes > = 10){
ClearInterval(法);
}
}
VaR方法= setInterval(间隔10);


字符串连接

如果要连接多个字符串,则应使用小于。


S =;
S=B;
S=C;


它应该被写为;

如果是字符串的集合,如许多相同的字符串=操作,最好使用缓存,使用Javascript数组进行收集,然后使用连接方法连接。


VaR buf = { };
对于(var i = 0;i < 100;i + +){
Buf.push(i.tostring());
}
所有变量= buf.join();


避免与报表

和功能是相似的,与语句将创建自己的范围,它会增加代码的执行范围链的长度,因为范围链额外的搜索,在语句中执行的代码必须执行的代码比外面要慢,不能用在句子尽量不使用With语句。


与(ABCD){
属性= 1;
财产= 2;
}
可以替换:
var obj = ABCD;
obj.property1 = 1;
obj.property2 = 2;


数字转换为字符串



最好使用+ 1将数字转换成字符串,尽管它看起来很难看,但实际上效率最高,


(+)>字符串()>。ToString()>新的字符串()




浮点数转换成整数



很多人喜欢使用parseInt()。事实上,parseInt()是用于将字符串转换为数字代替浮点数和整数之间的转换。我们应该用math.floor()或Math.round()。

各种类型的转换


变量myVar = 3.14159
str =+ / /串myVar
i_int = /整数~ ~ myVar。
f_float = 1×myVar /浮动
b_bool = myVar *!,布尔-任何长度的字符串
除0以外的任何数字都是正确的。
阵列= { myVar }; / /阵列




如果你定义了一个toString()进行类型转换的方法,建议显式调用toString(),因为内部操作后尝试所有的可能性,将对象的toString()方法尝试可以转化为字符串,所以直接调用此方法的效率会更高

多类型声明

在Javascript中,所有变量都可以由一个var语句声明。这是一个合并的语句,以减少整个脚本的执行时间。正如上面的代码一样,上述代码的格式也是非常标准的,以便人们能够清楚地看到它。

插入迭代器

例如,var名称=值i };i + +;前两个语句可以写成var名称=值

直接使用量


VaR测试=新(阵列); / /更换
VaR测试= { };
VaR测试=新对象; / /更换
VaR测试= { };
VaR reg =新(正则表达式); / /更换
var;
如果要创建一个通用对象具有一些特性,也可以使用文字,如下所示:
无功ofruit =新的O;
ofruit.color =红色;
ofruit.name =苹果;
代码可以在对象前面重写:
无功ofruit = {颜色:红色),名称:苹果};


使用documentfragment优化多个附加



一旦您需要更新DOM,考虑使用文档片段构建DOM结构,然后将其添加到现有文档中。


对于(var i = 0;i < 1000;i + +){
var el = document.createelement('p');
el.innerhtml =我;
document.body.appendchild(EL);
}
可以替换:
var = document.createdocumentfragment(片段);
对于(var i = 0;i < 1000;i + +){
var el = document.createelement('p');
el.innerhtml =我;
frag.appendchild(EL);
}
document.body.appendchild(片段);


使用innerHTML分配而不是建立一个DOM元素



大型DOM的变化,使用innerHTML比使用标准的DOM方法来创建相同的DOM结构快得多。


var = document.createdocumentfragment(片段);
对于(var i = 0;i < 1000;i + +){
var el = document.createelement('p');
el.innerhtml =我;
frag.appendchild(EL);
}
document.body.appendchild(片段);
可以替换:
var;
对于(var i = 0;i < 1000;i + +){
Html.push('+我+的);
}
html.join document.body.innerHTML =(' ');


而createElement通过模板分子克隆



很多人喜欢用document.write Javascript生成的页面内容。事实上,这种效率低。如果你需要直接插入HTML,你可以找到一个容器元素,如指定一个div或跨度,并设置其innerHTML插入自己的HTML代码插入到页面中。通常我们可以使用字符串直接写HTML创建节点,实际上,1不能保证2的字符串操作效率的代码的有效性很低,所以应该用(文档。createElement)方法,如果文档中的一个现成的模板节点应采用(clonenode)方法,因为使用的createElement()你需要设置多个元素属性的使用方法,clonenode()可以减少对相同的属性集数:如果你需要创建很多元素,应该先准备一个模板节点


var = document.createdocumentfragment(片段);
对于(var i = 0;i < 1000;i + +){
var el = document.createelement('p');
el.innerhtml =我;
frag.appendchild(EL);
}
document.body.appendchild(片段);
/ /更换:
var = document.createdocumentfragment(片段);
VaR像素= document.getelementsbytagname('p'){ 0 };
对于(var i = 0;i < 1000;i + +){
var el = pel.clonenode(假);
el.innerhtml =我;
frag.appendchild(EL);
}
document.body.appendchild(片段);


使用firstChild和nextSibling代替子节点遍历DOM元素




无功节点= element.childnodes;
对于(var i = 0,L = nodes.length;i < L;i++){
var节点=节点{ };
/……
}
可以替换:
var node = element.firstchild;
当(节点){
/……
节点= node.nextsibling;


删除节点

删除DOM节点之前,必须删除事件节点上注册,无论是注册在观察或attachevent模式,否则会产生不可逆转的记忆。此外,选择removechild和innerHTML =之间,后者。由于监测筛结果(内存泄漏监测工具)是removechild不能有效释放DOM节点的removechild。

使用事件代理

任何冒泡的事件不仅可以在目标上的任何事件的处理,目标祖先节点也可以处理,利用这方面的知识,你可以将事件处理程序附加到一个更高的地方多目标事件的处理,同样的,对于动态增加和子节点的内容需要相同的事件处理函数,可以使事件注册提到的父节点,这样就不需要每个子节点的事件侦听器登记。此外,现有的js库使用观察创建事件侦听器。事实上,它们隔离DOM对象和事件处理程序之间的循环引用,因此我们应该尝试使用这种方式创建事件侦听器。

重用调用结果,提前保存到本地变量


避免重复调用开销
VaR H1 = element1.clientheight + num1;
VaR H2 = element1.clientheight + num2;
可以替换:
无功eleheight = element1.clientheight;
VaR H1 = eleheight + num1;
VaR H2 = eleheight + num2;


注意列表

访问列表的数量最小化,可以大大提高脚本的性能


VaR('img图像= document.getelementsbytagname);
对于(var i = 0,len = images.length;我< len;i++){
}




编写Javascript的时候,一定要知道什么时候返回列表对象,这样可以减少对它们的访问

调用getElementsByTagName()了

得到的子元素的属性

获取元素的属性属性。

访问特殊的集合,如document.forms,document.images,等等

明白,当使用列表对象,合理的使用将大大提高代码的执行速度

最佳周期

下面的方法可以用来优化循环

减值迭代

大多数循环使用从0开始并添加到特定值的迭代器。在许多情况下,从最大值来看,循环中不断减少的迭代器效率更高。

简化的终止条件

因为每个周期计算终止条件,所以我们必须确保它尽快,这是避免属性查询或其他操作,最好是控制量的循环保存到一个局部变量,也就是说在数组或列表对象的遍历,保存长度提前一个地方变量,避免重复值的周期的每一步。


var list = document.getelementsbytagname('p');
对于(var i = 0;i < list.length;i++){
/……
}
替换:
var list = document.getelementsbytagname('p');
对于(var i = 0,L = list.length;i < L;i++){
/……
}


简化的循环体

循环体是执行最多的,所以要确保它优化到最大值。

使用后测试周期

在Javascript中,我们可以使用(())三个循环。,而()和(in)。事实上,这三个循环中的for(in)的效率非常低,因为他需要查询散列键,只要它们可以,就应该尽可能少地使用它们。for(;);while循环时,while循环比(;)更有效,这可能是因为for(())结构的问题,以及经常返回的需要。


var arr = { 1, 2, 3,4, 5, 6,7 };
var总和= 0;
对于(var i = 0,L = arr.length;i < L;i++){
总和= ARR {我};
}
可以替换为:
var arr = { 1, 2, 3,4, 5, 6,7 };
VaR和= 0,L = arr.length;
当(l){
总和= ARR {我};
}


循环和while循环最常用的都是预测试循环。例如,对DO-WHILE后测试循环可以避免初始终止条件的计算,所以它的运行速度。

展开的周期

当确定循环数时,消除循环并使用多个函数调用通常更快。

避免双重解释

如果要提高代码性能,请尽量避免需要用Javascript解释的字符串,即,

使用eval函数尽可能小

使用eval函数相当于发动机运行时解释器的运行了。经营内容要花很多时间,带来的eval的安全问题也不容忽视。

不要使用函数构造函数

不通过字符串参数setTimeout和setInterval


VaR数= 0;
setTimeout('num + +,10);
可以替换:
var = 0;
功能addnum(){
数字+;
}
setTimeout(addnum,10);


缩短检测为阴性


如果(抗议!=# FF0000){
做某事
}
如果(抗议!= NULL){
做某事
}
如果(抗议!= false){
做某事
}
尽管这些是正确的,但是非逻辑操作具有相同的效果:
如果(!抗议){
做某事
}


条件分支



在可能性的顺序上将条件分支从高到低排列:它可以减少解释器能够检测到的条件的次数。

在同一条件下的多(2)条件分支中,利用交换机优于if交换机分支的效率高于if,特别是在IE. 4分支测试下,IE下交换机的执行时间约为if的一半。



用三个网格运算符替换条件分支




如果((b){){
数字=;
{人}
数字=;
}
可以替换:
a;


使用常数

重复值:在多个地方使用的任何值都应作为常量提取。

用户界面字符串:应该向用户显示任何字符串,以便于国际化。

在Web应用程序中,资源的位置很容易更改,因此建议将所有URL存储在公共场所。

任何可以更改的值:每当使用文字值时,您必须询问自己这个值将来是否会改变。如果答案是肯定的,那么这个值应该被提取为常量。

避免与空比较

由于Javascript是一种弱类型,所以它不会进行任何类型的自动检查,所以如果您看到与null比较的代码,请尝试用以下技术替换。

如果该值应该是一个引用类型,使用instanceof检查它的构造函数

如果该值应该是一个基本类型,类型检查的动作类型

如果希望对象包含一个特定的方法的名称,typeof运算符用于确保对象上存在指定名称的方法

避免全球数量

全局变量应该在所有的大写字母,用来连接_下划线单词。避免使用全局变量和函数尽可能减少使用全局变量,因为包含所有页面中的Javascript是在同一个域中运行的,所以如果你的代码声明全局变量或全局函数,在脚本文件加载代码背后相同名称的变量和函数将覆盖你的覆盖。


全局变量和全局函数不正确
var =空;
函数init(){
…
}
函数更改(){
…
}
函数验证(){
…
}
有许多方法/解决方案,Christian Heilmann建议:
如果变量和函数不需要外部引用,那么您可以使用一个名称,它们都会被包装起来吗。
(函数(){())
var =空;
函数init(){
…
}
函数更改(){
…
}
函数验证(){
…
}
})();
如果外部引用中的变量和函数需要将变量和函数放在命名空间中。
我们在这里做的是名称空间,而不是一个带有函数语句的var,因为前者函数比较简单,而且可以保护数据的隐私性。
mynamespace =函数(){
var =空;
函数init(){
…
}
函数更改(){
…
}
函数验证(){
…
}
命名空间外部使用中所需的所有函数和属性都是以返回方式写入的。
返回{
init,
您甚至可以为函数和属性设置名称/别名。
设置:改变
};
};


尊重对象的所有权

因为Javascript可以在任何时候修改任何对象,因此您可以以意想不到的方式覆盖默认行为,所以如果您不负责维护对象、对象或方法,那么您不能用特定的点修改它:

不要将属性添加到实例或原型中

不要将一个方法添加到实例或原型中

不要重新定义现有的方法。

不要反复定义其他团队成员已经实现的方式。不要修改它,不要修改你所有的对象。可以通过以下方式创建对象的新函数。

创建一个包含所需函数的新对象,并使用它与相关对象进行交互

创建自定义类型,继承需要修改的类型,并向自定义类型添加其他功能



循环引用

如果在循环引用中包含DOM对象或ActiveX对象,则会发生内存泄漏。内存泄漏的后果是,在浏览器关闭之前,即使刷新页面,内存的这一部分也不会被浏览器释放。

简单循环引用:


var el = document.getelementbyid('myelement);
函数(){()
…
}
el.func =功能;
func.element = EL;




但这通常不会发生。通常发生在一个封闭的循环引用添加到DOM元素作为expendo。


函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
}
init();


当init被执行时,当前上下文称为上下文。此时,上下文引用EL、EL引用函数和函数引用上下文。此时形成一个循环引用。

以下2种方法可以用来解决循环引用:

1)空DOM对象


函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
}
init();
可以替换:
函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
EL = null;
}
init();


EL是空的,上下文不包含对DOM对象的引用,因此中断了循环应用程序。

如果我们需要返回DOM对象,我们可以使用以下方法:


函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
返回El;
}
init();
可以替换:
函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
{试
返回El;
{最后}
EL = null;
}
}
init();


2)构建新的语境


函数init(){
var el = document.getelementbyid('myelement);
el.onclick =函数(){
/……
}
}
init();
可以替换:
功能elclickhandler(){
/……
}
函数init(){
var el = document.getelementbyid('myelement);
el.onclick = elclickhandler;
}
init();


函数被注入到一个新的上下文中,这样函数的上下文中不包含对EL的引用,从而中断循环引用。

Javascript创建的DOM对象必须追加到页面中。



在IE中,由脚本创建的DOM对象,不附加页面,刷新页面,内存的这一部分将不会被回收!


函数创建(){
VaR GC = document.getelementbyid('gc);
对于(var i = 0;i < 5000;i + +){
var el = document.createelement('div);
el.innerhtml =测试;
它可以在任务管理器中删除浏览器,然后单击按钮刷新内存变化。
gc.appendchild(EL);
}
}


释放DOM元素占用的内存

该DOM元素的innerHTML设置为空字符串,它可以释放内存占用的子元素。

在丰富的应用程序中,用户可以在页面上停留很长一段时间,这可以用来释放积累越来越多DOM元素的内存。

Javascript对象的释放

在丰富的应用程序中,随着实例化对象数量的增加,内存消耗将变得越来越大,因此应该及时释放对对象的引用,以便GC可以回收这些内存控件。

对象:对象= null

对象属性:删除obj.myproperty

数组项:使用数组的拼接方法释放数组中未使用的项。

避免字符串的隐式包装



方法调用的字符串,这样的as'xxx。长度,浏览器执行隐式装箱操作,转换成一个字符串的字符串对象。以下是推荐一个字符串声明字符串实例的方法是可能的:


建立字符串=新的字符串('Hello World);


松散耦合

1。解耦html / Javascript

Javascript和HTML之间的紧密耦合直接用HTML编写,使用包含内联代码的元素,并将事件处理程序分配给HTML属性。

HTML和Javascript的紧密耦合:Javascript包含HTML,然后innerHTML是用来插入一段HTML文本在页面

事实上,我们应该保持层的分离,这样我们就可以很容易地识别错误的来源,所以我们应该尽可能地将HTML表示与Javascript分开。

2。解耦CSS / Javascript

只显示问题的源头应该是CSS,行为问题的唯一来源应该是Javascript,之间的松散耦合的水平可以使你的程序更容易维护,所以像下面的代码元素。风格。颜色=红色元素。类名=编辑,但不是通过Javascript CSS表达式

三.去耦应用程序/事件处理程序

应用程序逻辑与事件处理程序分离:从事件对象中提取一个事件处理程序,并发送到某个处理应用程序逻辑的方式。第二,您可以在没有附加事件的情况下测试代码,从而更容易地创建单元测试。

重视绩效

1。尽可能使用本机方法。

2,开关语句相对于

以最可能的顺序组织案例陈述,以最不可能的顺序

3,位运算速度快。

当执行数字运算时,位运算比任何布尔运算或算术运算都快。

4、使用| |和布尔运算符


功能EventHandler(e){
如果(!E)E = window.event;
}
可以替换:
功能EventHandler(e){
E = e window.event | |;
}
如果(myobj时){
DoSomething(myobj时);
}
可以替换:
Myobj doSomething(myobj时);


避免错误的地方

1。必须在每个语句的结尾加上分号。

在if语句中,即使条件表达式只有一个语句也应该在括号中使用它,以免在语句引起逻辑错误之后添加后续语句。

2。使用+号是谨慎的。

Javascript等编程语言,Javascript是不同的,除了+表示数字值的字符串连接外,也可以是一元运算符,将字符串转换为数字。如果使用不当,它可能与自福+混乱造成的误判增加


VaR值= 20;
var b =10;
警报(价值+ b); / /输出:2010
警报(值+(+ b)); / /输出:30
警报(价值+ b); / /输出:30
警报(价值+ b); / /编译错误




三.应注意使用返回语句。

不应该使用返回值的返回语句来将返回值括起来(括号)。如果返回表达式,表达式应该与返回关键字在同一行上,以避免压缩。压缩工具自动添加分号,导致与开发人员不一致的结果。


函数f1(){
VaR值= 1;
var b = 2;
返回值+ b;
}
函数F2(){
VaR值= 1;
var b = 2;
返回
值+ b;
}
警报(f1());输出:3
警报(F2()); / /输出:未定义


=和=差

避免在while和while条件下赋值,例如如果(a = b),应该是(a = b),但在相等情况下,最好使用全等运算符,运算符== =!= =,将是一个好点!=运算符类型强制


VaR值=1;
var b = 1;
如果(值= = b){
警报();
}
{其他
警报(不等于);
}
输出:
如果(值= b){
警报();
}
{其他
警报(不等于);
}
输出:不等于


不要使用语法语法



不要使用语法语法,编写混乱的代码,虽然计算机能正确识别和运行,但晦涩的代码不便于以后维护。

函数返回统一类型



虽然Javascript是弱类型,但对于函数,整数数据在返回之前,在编译和运行之后,布尔值将返回到正常值。然而,为了便于标准化和维护,我们应该确保函数返回到统一的数据类型。

始终检查数据类型



检查所有的你的方法输入数据,另一方面,它是对可用性的安全,另一方面,用户会输入了错误的数据和任何地方。这不是因为他们傻,而是因为他们很忙,不同于你的想法。使用typeof方法检测你的函数接受输入的是合法的

何时使用单引号和何时使用双引号



虽然在javascript中,双引号和单引号可以说是字符串,为了避免混淆,我们建议在HTML中使用双引号,在javascript中使用单引号,但为了与每个浏览器兼容,也要解决无错误,定义JSON对象,最好使用双引号。

部署



运行JSLint Javascript验证器来确保没有语法错误或代码没有潜在的问

在部署之前,js文件是使用压缩工具压缩的。



统一使用UTF-8编码的文件



Javascript程序应该放在js文件尽可能,并应包括在HTML表格的时候,你需要调用它。如果Javascript代码不专用于HTML文件,你应该尽量避免写Javascript代码直接在HTML文件,因为这将大大增加。HTML文件的大小,这是不利于代码的压缩和缓存的使用。此外,标签应放置在文件的后面尽可能,最好是在前面的标签。这减少了页面中的其他组件的加载时间,加载Javascript代码。

永远不要忽视代码优化。重构是一个持续不断的工作。只有不断优化代码,才能使代码执行效率越来越好。