高性能javascript读书笔记(2)

书《高性能javascript》中英文对照版

接(1)https://blog.csdn.net/u011393161/article/details/79790387

6。响应接口

尽量将(交互操作)js的运行时间缩短到100ms内

有多个items需要长时间处理的时候,尽量分解为多步处理

function processArray(items, process, callback){
    var todo = items.concat(); //create a clone of the original
    setTimeout(function(){
        process(todo.shift());
    if (todo.length > 0){
        setTimeout(arguments.callee, 25);
    } else {
        callback(items);
    }
    }, 25);
}

一些耗时的函数需要执行

function multistep(steps, args, callback){
    var tasks = steps.concat(); //clone the array
    setTimeout(function(){
        //execute the next task
        var task = tasks.shift();
        task.apply(null, args || []);
        //determine if there's more
        if (tasks.length > 0){
            setTimeout(arguments.callee, 25);
        } else {
            callback();
        }
    }, 25);
}

一次定时时间内执行多个操作

function timedProcessArray(items, process, callback){
    var todo = items.concat(); //create a clone of the original
    setTimeout(function(){
        var start = +new Date();
        do {
            process(todo.shift());
        } while (todo.length > 0 && (+new Date() - start < 50));
        if (todo.length > 0){
            setTimeout(arguments.callee, 25);
        } else {
            callback(items);
        }
    }, 25);
}

web worker具有这些对象:

一个浏览器对象,包含appName, appVersion, userAgent,  platform属性,
一个location对象,属性只读
一个self,表示当前worker
一个importScripts()方法,可以引用其他文件
ECMAScript原生对象,Object Array Data等
XMLHttpRequest构造器
setTimeout和setInterval
close()方法,用于停止worker

postMessage可以传递Object和Array,以及string number boolean null undefined

importScripts()阻塞worker执行,importScripts的文件加载并执行完之后,才执行importScripts后面的语句,再次提醒是执行完之后

7。Ajax 异步JavaScript和XML

一个比平时更加标准一点的get,主要是多了X-Requested-With和getAllResponseHeaders,X-Requested-With这个头是有用的,遇到过一次服务端同学说判断不出我发的请求是不是ajax的情况,说我发的请求没有X-Requested-With这个头信息

var url = '/data.php';
var params = [
    'id=934875',
    'limit=20'
];
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
    if (req.readyState === 4 && 
    (req.status >= 200 && req.status < 300 || req.status != 304)) {
        var responseHeaders = req.getAllResponseHeaders(); // Get the response headers.
        var data = req.responseText; // Get the data.
        // Process the data here...
    }
}
req.open('GET', url + '?' + params.join('&'), true);
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); // Set a request header.
req.send(null); // Send the request.

这里插播一下split函数,因为书里提到了自定义格式的协议,一般是自己定义一个分隔符

// 1.split是可以用正则表达式的
var a = "1 2 3 4 5 6 7 8 9";
var b = a.split(/\s/);
// 2.split可以带第二个参数,截取最后分隔的结果
// 3.不对源数组进行修改

8。编程实践

隐藏的重复操作,比如,对于IE和其他浏览器的不同的事件绑定函数

function addHandler(target, eventType, handler){
    if (target.addEventListener){ //DOM2 Events
        target.addEventListener(eventType, handler, false);
    } else { //IE
        target.attachEvent("on" + eventType, handler);
    }
}

功能上没问题,不过每次执行都判断target.addEventListener,可以在第一次检测之后覆盖addHandler函数,避免下次继续判断。注意借鉴这个思想,而不只是借鉴这个情景

js的数字是32位有符号数(之前没注意过),如果要进行二进制操作,可以使用toString(x),x要在2-36之间,你猜为什么是36(滑稽)

var a = 123;
var b = a.toString(16); //'7b',注意是小写的英文而且没有0x打头
//顺便,js可以给变量赋0x123,0b110,0123这样的值,分别是16进制,2进制,8进制

一些位操作,虽然平时用到的少

var result1 = 25 & 3; //1 都转成二进制,3的高位补0进行运算
var result = ~25; //-26 看看这位大佬,简直神奇

来看看大佬为什么这么神奇,首先有符号数都是用补码来存储的,这是第一前提
然后正数的补码就是自身,负数的补码是反码+1
而反码是对原码的除符号位外的其他位进行取反的结果

举例:

比如8位存储的-1的二进制反码是1110,二进制补码是1111
对1111做个按位取反,得到0000,是-1按位取反的结果的补码
这个补码是个正数,所以结果就是自身,所以-1按位取反的结果是0

再比如8位存储的2,存储的二进制补码是0010
取反是1101,是2按位取反的结果的补码
这个补码是个负数,所以先减1得到结果的反码1100
然后再取反得到结果1011,也就是-3

平时有一些操作感觉很自然,不会觉得有什么不多,但是确实比位操作慢,不过一般不太需要优化到这种程度,比如i % 2判断变量i是不是偶数,可以替换成i & 1,因为存储的时候偶数最低位是0

还有一个场景是掩码,判断的选项一定要是2的幂

var OPTION_A = 1;
var OPTION_B = 2;
var OPTION_C = 4;
var OPTION_D = 8;

if (options & OPTION_A){
    //do something
}
if (options & OPTION_B){
    //do something
}

Math有一些内置的属性和方法,尽量使用这些属性和方法,不要自己计算,可以参考
https://www.cnblogs.com/susufufu/p/5846306.html

9。部署相关内容,跳过

10。工具,跳过

猜你喜欢

转载自blog.csdn.net/u011393161/article/details/80061389