发表于: 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()。

改良版本道理是一样的。

差异猜测,减少了大量的数据比较,直接进行数据操作,估计数据比较占用了相当大的一部分运行时间。

    

收获:

高程后面的内容说到的一些优化程序的方法。



返回列表 返回列表
评论

    分享到