避免全局查找
在一个函数中会用到全局对象存储为局部变量来减少全局查找,因为访问局部变量的速度要比访问全局变量的速度更快些
function search() {
// 当我要使用当前页面地址和主机域名
alert(window.location.href + window.location.host)
}
// 最好的方式是如下这样 先用一个简单变量保存起来
function search() {
var location = window.location
alert(location.href + location.host)
}
定时器
如果针对的是不断运行的代码,不应该使用 setTimeout,而应该是用 setInterval,因为 setTimeout 每一次都会初始化一个定时器,而 setInterval 只会在开始的时候初始化一个定时器
var timeoutTimes = 0
function timeout() {
timeoutTimes++
if (timeoutTimes < 10){
setTimeout(timeout, 10)
}
}
timeout()
// 可以替换为
var intervalTimes = 0
function interval() {
intervalTimes++
if (intervalTimes >= 10){
clearInterval(interv)
}
}
var interv = setInterval(interval, 10)
字符串连接
如果要连接多个字符串,应该少使用 +=,如
s+=a
s+=b
s+=c
应该写成 s+=a + b + c
二如果是收集字符串,比如多次对同一个字符串进行+=操作的话,最好使用一个缓存,使用JavaScript 数组来收集,最后使用 join 方法连接起来
var buf = []
for (let i = 0;i < 100;i++){
buf.push(i.toString())
}
var all = buf.join("");
数字转字符串
一般最好用 "" + 1 来将数字转换成字符串,虽然看起来比较丑一点,但事实上这个效率是最高的,性能上来说:
(""+)>String()>.toString()>new String()
浮点数转换成整型
很多人喜欢使用 parseInt(),其实 parseInt() 是用于将字符串转换成数字,而不是浮点数和整型之间的转换,我们应该使用 Math.floor()去掉小数部分,负数减一去掉小数
或者 Math.round()四舍五入
各种类型的转换
var myVar = "3.14159",
str = "" + myVar, // to string
i_int = ~~myVar, // to integer
f_float = 1 * myVar, // to float
b_bool = !!myVar, /* to boolean - any string with length
and any number except 0 are true */
array = [myVar]; // to array
如果定义了 toString() 方法来进行类型转换的话,推荐显式调用 toString(),因为内部的操作在尝试所有可能性之后,会尝试对象的 toString() 方法尝试能否转化为 String,所以直接调用这个方法效率会更高
多个类型声明
在 JavaScript 中所有变量都可以使用单个 var 语句来声明,这样就是组合在一起的语句,以减少整个脚本的执行时间,就如上面代码一样,上面代码格式也挺规范,让人一看就明了。
插入迭代器
如var name=values[i];i++;
前面两条语句可以写成var name=values[i++];
使用直接量
var aTest = new Array() // 替换为
var aTest = [];
var aTest = new Object // 替换为
var aTest = {};
var reg = new RegExp(); // 替换为
var reg = /../;
//如果要创建具有一些特性的一般对象,也可以使用字面量,如下:
var oFruit = new O;
oFruit.color = "red";
oFruit.name = "apple";
//前面的代码可用对象字面量来改写成这样:
var oFruit = { color: "red", name: "apple" };
使用 DocumentFragment 优化多次 append
一旦需要更新 DOM, 请考虑使用文档碎片来构建 DOM 结构,然后再将其添加到现存的文档中。
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
document.body.appendChild(el);
}
//可以替换为:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
使用一次 innerHTML 赋值代替构建 dom 元素
对于大的 DOM 更改,使用 innerHTML 要比使用标准的 DOM 方法创建同样的 DOM 结构快得多。
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
//可以替换为:
var html = [];
for (var i = 0; i < 1000; i++) {
html.push('<p>' + i + '</p>');
}
document.body.innerHTML = html.join('');
通过模板元素 clone,替代 createElement
很多人喜欢在 JavaScript 中使用 document.write 来给页面生成内容。事实上这样的效率较低,如果需要直接插入 HTML,可以找一个容器元素,比如指定一个 div 或者 span,并设置他们的 innerHTML 来将自己的 HTML 代码插入到页面中。通常我们可能会使用字符串直接写 HTML 来创建节点,其实这样做,1 无法保证代码的有效性 2 字符串操作效率低,所以应该是用 document.createElement() 方法,而如果文档中存在现成的样板节点,应该是用 cloneNode() 方法,因为使用 createElement() 方法之后,你需要设置多次元素的属性,使用 cloneNode() 则可以减少属性的设置次数——同样如果需要创建很多元素,应该先准备一个样板节点
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
//替换为:
var frag = document.createDocumentFragment();
var pEl = document.getElementsByTagName('p')[0];
for (var i = 0; i < 1000; i++) {
var el = pEl.cloneNode(false);
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);