JavaScript代码最好的写法

JavaScript代码的速度被分成两部分:下载时间和执行速度。

Web浏览器下载的是js源码,因此所有长变量名和注释都回包含在内。这个因素会增加下载时间。1160是一个TCP-IP包中的字节数。最好能将每个javascript文件都保持在1160字节以下以获得最优的下载时间。 

   由于这个原因,要删除注释、删除制表符和空格、删除所有的换行、将长变量名缩短。
遵循这4条比较困难。因此用外部程序(ECMAScript Cruncher)来帮助我们。

要运行ESC,必使用Windows系统,打开一个控制台窗口,然后使用以下格式的命令:

cscript ESC.wsf -l [0-4] -ow outputfile.js inputfile1.js [inputfile2.js]

 第一部分,cscript,是Windows Shell脚本解释程序。文件名ESC.wsf是ESC的程序本身。然后是压缩级别,一个0到4的数值。-ow选项表示下一个参数是优化后输出的文件名。最后,剩下的参数是要进行优化的JavaScript文件,可以有多个文件(多个文件在优化后后会按顺序放到输出文件中)。

0 —— 不改变脚本,要将多个文件拿到单个文件中时用用。

1 —— 删除所有的注释。

2 —— 除等级1外,再删除额外的制表符和空格。

3 —— 除等级2外,再删除换行。

 

4 —— 除等级3外,再进行变量名替换。

ESC擅长把变量名替换成无意义的名称,它还具有一定的智能,进行私有对象先进性和方法名的替换(由名称前后加上两个下划线表示),所以私有特性和方法依然保持其私有性。

ESC不会更改构造函数名、公用属性和公用方法名,所以无需担心。但要注意的是如果某个JavaScript引用了另一个文件中的构造函数,4级优化会把对构造函数的引用替换成无意义的名称。解决方法是将两个文件合成一个文件,这样就会保持构造函数的名称。

====================================

   其他减少字节数的方法还有几个。
     1.因为在javascript语言中 true等于1,false等于0。因此,脚本包含的字面变量true都可以用1来替换,而false可以用0来替换。
例如:

var bFound = false;
for (var i = 0; i < aTest.length && !bFound; i++) {
 if (aTest[i] == vTest) {
  bFounde = true;
 }
}

var bFound = 0;
for (var i = 0; i < aTest.length && !bFound; i++) {
 if (aTest[i] == vTest) {
  bFounde = 1;
 }
}

  2.缩短否定检测

if (oTest != undefined) {
  //do someting
}
if (oTest != null) {
 //do someting
}
if (oTest != false) {
  //do someting
}

可以替换成

if (!oTest) {
//do something

 3.减少语句数量
var iFive = 5;
var sColor = "blue";

可以为

var iFive = 5, sColor = "blue";

var sName = aValues[i];
i++;
//可以替换成
var sName = aValues[i++];

  

◆字符串的使用

在IE6和IE7中因字符串级联导致的主要问题是垃圾回收性能,虽然这些问题在IE8中已经得到解决,但如果你的用户大部分仍然在使用IE或IE7,你就得格外注意这个问题了。看一个例子先:

var veryLongMessage = "This is a long string that due to our strict line length limit of"
+ maxCharsPerLine + " characters per line must be wrapped. "
+ percentWhoDislike + "% of engineers dislike this rule. The line length limit is for "
+ " style purposes, but we don't want it to have a performance impact."
+ " So the question is how should we do the wrapping?";

可以使用连接代替级联:

var veryLongMessage = ["This is a long string that due to our strict line length limit of",
maxCharsPerLine,
" characters per line must be wrapped. ",
percentWhoDislike,
"% of engineers dislike this rule. The line length limit is for ",
" style purposes, but we don't want it to have a performance impact.",
 " So the question is how should we do the wrapping?"].join();

 

 ◆与此类似,在条件语句中使用级别也是很低效的,错误的做法:

var fibonacciStr = "First 20 Fibonacci Numbers ";
for (var i = 0; i < 20; i++) {
 fibonacciStr += i + " = " + fibonacci(i) + " ";
}

最好的方法是:

var strBuilder = ["First 20 fibonacci numbers:"];
for (var i = 0; i < 20; i++) {
 strBuilder.push(i, " = ", fibonacci(i)," ");
}
var fibonacciStr = strBuilder.join(""); 

◆定义类函数

下面的函数是低效的,因为每次构造baz.Bar的实例时,会创建一个新的函数和闭包:

baz.Bar = function () {

  // constructor body
 this.foo = function () {

  // method body
 };
};

正确的方法是:

baz.Bar = function () {

  // constructor body
 this.foo = function () {

  // method body
 };
};
baz.Bar = function () {

  // constructor body
};
baz.Bar.prototype.foo = function () {

  // method body
};

使用这个方法时,无论baz.Bar构造了多少个实例,都只会为foo创建一个函数,而且不会创建闭包。

◆初始化实例变量

使用实例变量值类型初始值初始化实例变量声明,如数值、布尔值、空值、未定义或字符串,这样可以避免每次调用构造器时运行不必要的初始化代码。还是来看一个例子:

foo.Bar = function () {
 this.prop1_ = 4;
 this.prop2_ = true;
 this.prop3_ = [];
 this.prop4_ = "blah";
};

可以代替为:

foo.Bar = function () {
 this.prop3_ = [];
};
foo.Bar.prototype.prop1_ = 4;
foo.Bar.prototype.prop2_ = true;
foo.Bar.prototype.prop4_ = "blah";

◆避免使用with

避免在代码中使用with,它会影响到性能,因为它修改了范围链,因此需要花费更多时间到其它范围去查找。

 

◆尽可能避免使用全局变量和函数.
全局的变量和函数其实等价于 window 对象的属性/方法, 访问速度自然会慢.

var myvar = 0; // 336ms
window.myvar = 0; // 2383ms

var myfunc = function(){} // 3515ms
window.myfunc = function(){} // 10151ms


◆尽量避免用 new 操作符创建函数.
可能通过 new 创建的函数还需要额外地对函数内容字符串进行解析操作.

function f(){}; // 277ms
var f  = function(){} // 3085ms
var f = new Function("") // 13275ms


◆尽量避免使用 eval() 执行代码.
原因同 new 创建函数的操作.

 var myfunc = function(){} // 3408ms
eval("var myfunc = function(){}"); // 9140ms

 

◆少使用 new 操作符创建数组.
原因同 new 创建函数的操作. 特别在有大量数据时更为明显

a = [1, 2, 3]; // 4360ms
a = new Array(1, 2, 3); // 5000ms

 

◆尽量避免使用 push() 和 pop() 处理数组数据.

a[i] = value; // 1270ms
a.push(value); // 3240ms

 

◆使用对象代替数组存储数据对性能略有影响.
也许是因为 Javascript 的数组是个带有扩展方法和属性的对象, 而不像 VBScript 那样是单纯的数据结构.

a[i] = value; // 1270ms
obj[property] = value; // 960ms

 

◆使用 ++ 代替 x = x+1 和 +=.
事实上 ++ 并不比 + 和 += 快很多, 但是在大量的操作时就会体现出其优势.
而 + 和 += 几乎没有性能差别. 同理对 -- 和 - 以及 -= 适用.

x++; // 378ms
x = x+1; // 406ms
x += 1; // 406ms

 

◆使用局部变量缓存对象属性和函数指针
例如在遍历数组时缓存数组长度, 事实上获取 Javascript 的数组长度等于调用一个方法函数(大部分Javascript 引擎是这样实现的).
如果对 HTML DOM 进行操作, 那么优化的效果会非常明显.

for(var i=0;i<arr.length;i++){ ... } // 162ms

var length = arr.length;
for(var i=0;i<length;i++){ ... } // 156ms

或者使用局部变量缓存一个外部函数(具体效果视代码复杂度而定).
如果代码块中要多次调用一个外部函数或变量, 那么缓存的效果会非常明显.

function test(){ ... }
function run1(){  test(); }
function run2(){  var t = test;  t(); }

run1(); // 98ms
run2(); // 80ms

转自:http://jiangzhengjun.javaeye.com/

转载于:https://www.cnblogs.com/jclser/archive/2010/02/17/1668922.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值