发表于: 2017-05-12 21:45:50
1 992
完成的事情:
好吧,才是差不多看完高程,还是跳过了一些不太重要、不太常用的内容。
计划的事情:
开始jquery的内容,因为jquery是基于javascript的框架,如果没什么啥新东西,就快速过一遍,然后尝试编写轮播图插件。
问题:
挑几个好用的说吧
1、作用域的安全问题
function Person(name, age, job){
if (this instanceof Person){
this.name = name;
this.age = age;
this.job = job;
} else {
return new Person(name, age, job);
}
}
新建那个啥,构造函数的时候,这样可以避免
var person = Person('a','b','c')
而非var person = new Person('a','b','c')
时候,出现的this指向window作用域的结果
2、定时器看起来像是异步进行的东西,其实也就是把一个事件加入到javascript的事件处理列表当中,前面的都完成了,轮到它的时候才执行代码。
for(var i=0; i<10; i++){
(function(a){
var sum = a;
setTimeout(function(){
for(var i=0; i<100000000; i++){
sum += i;
}
console.log(sum);
},a*100);
})(i);
}
这样的一段代码就可以测试出来,理应当是每100ms输出一个sum,但实际上是大概1s输出一个,而且在此循环执行期间,页面的其他操作,例如点击事件、拖动事件,完全没有响应,由此可知,定时器也是属于javascript的单线程事件。
若想要改变上面的没有响应的问题,可以把for循环内的数据拆分成多组,每100ms左右执行一组直到执行完全部数据,当然,此办法只能对那些对响应时间要求不是很高的数据有效,若重要数据,那就。。。让用户等等吧。
3、针对循环操作大量数据的速度问题,在这里介绍一个叫做Duff装置的方法,先看下面的代码:
var sum = 0;
function process(v) {
sum += v
}
var values = [];
for(var o=0; o<1000000; o++){
values[o] = o;
}
console.time('aa');
for(var p=0; p<values.length; p++){
process(values[p]);
}
console.timeEnd('aa');
console.log(sum);
console.time('bb');
var iterations = Math.ceil(values.length / 8);
var startAt = values.length % 8;
var i = 0;
do {
switch(startAt) {
case 0 : process(values[i++]);
case 7 : process(values[i++]);
case 6 : process(values[i++]);
case 5 : process(values[i++]);
case 4 : process(values[i++]);
case 3 : process(values[i++]);
case 2 : process(values[i++]);
case 1 : process(values[i++]);
}
startAt = 0;
}while(--iterations>0);
console.timeEnd('bb');
console.log(sum);
console.time('cc');
var iterations2 = Math.floor(values.length / 8);
var startAt2 = values.length % 8;
var j = 0;
if(startAt2>0){
do {
process(values[j++]);
} while (--startAt2 > 0);
}
do {
process(values[j++]);
process(values[j++]);
process(values[j++]);
process(values[j++]);
process(values[j++]);
process(values[j++]);
process(values[j++]);
process(values[j++]);
}while(--iterations2>0);
console.timeEnd('cc');
console.log(sum);
aa:普通的一个for循环
bb:Duff装置的最初版本
cc:Duff装置的改良版本
运行结果:
非常明显的时间差。
Duff 初版装置的实现是通过将values 数组中元素个数除以8 来计算出循环需要进行多少次迭代的。然后使用取整的上限函数确保结果是整数。如果完全根据除8 来进行迭代,可能会有一些不能被处理到的元素,这个数量保存在startAt 变量中。首次执行该循环时,会检查StartAt 变量看有需要多少额外调用。例如,如果数组中有10 个值,startAt 则等于2,那么最开始的时候process()则只会被调用2 次。在接下来的循环中,startAt 被重置为0,这样之后的每次循环都会调用8 次process()。
改良版本道理是一样的。
差异猜测,减少了大量的数据比较,直接进行数据操作,估计数据比较占用了相当大的一部分运行时间。
收获:
高程后面的内容说到的一些优化程序的方法。
评论