一直在学习javascript,也有看过《犀利开发Jquery内核详解与实践》,对这本书的评价只有两个字犀利,多是对javascript理解的还不够透彻异或是本身太笨,更多的是本身不擅于思考懒得思考以致于里面说的一些精髓都没有太深刻的理解。javascript
鉴于想让本身有一个提高,进不了一个更加广阔的天地,总得找一个属于本身的居所好好生存,因此平时会有意无心的去积累一些使用jQuerry的经常使用知识,特别是对于性能要求这一块,老是会想是否是有更好的方式来实现。html
下面是我总结的一些小技巧,仅供参考。(我先会说一个总标题,而后用一小段话来讲明这个意思 再最后用一个demo来简单言明)java
避免全局查找node
在一个函数中会用到全局对象存储为局部变量来减小全局查找,由于访问局部变量的速度要比访问全局变量的速度更快些数组
function search() {缓存
//当我要使用当前页面地址和主机域名app
alert(window.location.href + window.location.host);dom
}函数
//最好的方式是以下这样 先用一个简单变量保存起来工具
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 (var i = 0; i < 100; i++) {
buf.push(i.toString());
}
var all = buf.join("");
避免with语句
和函数相似 ,with语句会建立本身的做用域,所以会增长其中执行的代码的做用域链的长度,因为额外的做用域链的查找,在with语句中执行的代码确定会比外面执行的代码要慢,在能不使用with语句的时候尽可能不要使用with语句。
with (a.b.c.d) {
property1 = 1;
property2 = 2;
}
//能够替换为:
var obj = a.b.c.d;
obj.property1 = 1;
obj.property2 = 2;
数字转换成字符串
般最好用”" + 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);
使用firstChild和nextSibling代替childNodes遍历dom元素
\
var nodes = element.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i];
//……
}
//能够替换为:
var node = element.firstChild;
while (node) {
//……
node = node.nextSibling;
删除DOM节点
删除dom节点以前,必定要删除注册在该节点上的事件,不论是用observe方式仍是用attachEvent方式注册的事件,不然将会产生没法回收的内存。另外,在removeChild和innerHTML=’’两者之间,尽可能选择后者。 由于在sIEve(内存泄露监测工具)中监测的结果是用removeChild没法有效地释放dom节点
使用事件代理
任何能够冒泡的事件都不只仅能够在事件目标上进行处理,目标的任何祖先节点上也能处理,使用这个知识就能够将事件处理程序附加到更高的地方负责多个目标的事件处理,一样,对于内容动态增长而且子节点都须要相同的事件处理函数的状况,能够把事件注册提到父节点上,这样就不须要为每一个子节点注册事件监听了。另外,现有的js库都采用observe方式来建立事件监听,其实现上隔离了dom对象和事件处理函数之间的循环引用,因此应该尽可能采用这种方式来建立事件监听
重复使用的调用结果,事先保存到局部变量
//避免屡次取值的调用开销
var h1 = element1.clientHeight + num1;
var h2 = element1.clientHeight + num2;
//能够替换为:
var eleHeight = element1.clientHeight;
var h1 = eleHeight + num1;
var h2 = eleHeight + num2;
注意NodeList
最小化访问NodeList的次数能够极大的改进脚本的性能
var images = document.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
}
编写JavaScript的时候必定要知道什么时候返回NodeList对象,这样能够最小化对它们的访问
进行了对getElementsByTagName()的调用武汉精神分裂医院哪一个好
获取了元素的childNodes属性
获取了元素的attributes属性
访问了特殊的集合,如document.forms、document.images等等
要了解了当使用NodeList对象时,合理使用会极大的提高代码执行速度