高性能JavaScript笔记三(编程实践)

避免双重求值

有四个标准函数可以允许你传入代码的字符串,然后它才你动态执行。它们分别是:eval、Function、setTimeout、setInterval

事实上当你在javascript代码中执行另外一段javascript代码时,都会导致双重求值的性能消耗,所以在大多数情况下,没必要使得eval和Function函数,因此最好避免使用它们。至于setTimeout和setInterval,建议传入函数而不是字符串来作为第一个参数

现在Safari4和chrome的javaScript引擎会缓存住那些使用了eval且重复运行的代码,这也是一个性能提升点。

使用Object/Array直接量

使用直接量的两大好处

  1. 运行速度更快
  2. 节省代码量、减少文件尺寸(事实上对象属性或者数组项数量越多,使用直接量的好处就越明显)

不要重复工作

有两种方法避免重复工作

  1. 延迟加载
  2. 条件预加载

以一个例子来说明吧

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

事实上页面一加载,你就知道用户是使用的哪种浏览器,但是这时候如果页面上有100个元素需要添加事件绑定就需要判断100次(而本身事实上你只需要去判断一次)

下面使用延迟加载的方式来试试

        function addHandler(target, eventType, handler) {
            if (target.addEventListener) {//DOM2 Events
                addHandler = function (target, eventType, handler) {
                    target.addEventListener(eventType, handler, false);
                }
            } else {//IE
                addHandler = function (target, eventType, handler) {
                    target.attachEvent('on' + eventType, handler);
                }
            }
            addHandler(target, eventType, handler);//调用新的函数
        }
        function removeHandler(target, eventType, handler) {
            if (target.removeEventListener) {//DOM2 Events
                removeHandler = function (target, eventType, handler) {
                    target.removeEventListener(eventType, handler, false);
                }
            } else {//IE
                removeHandler = function (target, eventType, handler) {
                    target.detachEvent('on' + eventType, handler);
                }
            }
            removeHandler(target, eventType, handler);//调用新的函数
        }

调用延迟加载函数时,第一次会相对慢些,后面每次调用时都会很快,所以当一个函数在页面中不会立即调用时,延迟加载是最好的选择

另外一种方式是使用条件预加载:会在脚本加载期间提单检测,而不会等到函数被调用

        var addHandler = document.body.addEventListener ?
            function (target, eventType, handler) {
                target.addEventListener(eventType, handler, false);
            } :
            function (target, eventType, handler) {
                target.attachEvent('on' + eventType, handler);
            };


        var removeHandler = document.body.removeEventListener ?
            function (target, eventType, handler) {
                target.removeEventListener(eventType, handler, false);
            } :
            function (target, eventType, handler) {
                target.detachEvent('on' + eventType, handler);
            };

 

位操作

javascript中的数字都是以64位格式进行存储的,在位操作中,数字被转换为有符号32位格式,每次运算都是直接操作该32位数得到结果,事实上javascript位操作比其它数学运算和布尔运算操作都要快

举例来说明一下

1、对2取模,一般性的大家会如下这样写

        if (i % 2) {
            //是奇数
        } else {
            //是偶数
        }

但下面这样写会更快些

        if (i & 1) {
            //是偶数
        } else {
            //是奇数
        }

2、位掩码(也就是使用单个数字的每一位来判定是否选项成立,从而有效的把数字转换为由布尔值标记组成的数组)示例代码如下所示

        var OPTION_A = 1;
        var OPTION_B=2;
        var OPTION_C = 3;
        var OPTION_D = 4;
        var options = OPTION_A | OPTION_B | OPTION_C | OPTION_D;
        if (options&OPTION_A) {
            //选项a在列表中,进行处理processing
        }
        if (options & OPTION_B) {
            //选项b在列表中,进行处理processing
        }

 

使用原生方法

无论你的javascript如何优化,都不会比js引擎提供的原生方法更快,原因很简单这些原生方法在你写代码之前就已经存在浏览器中了,并且是使用低级语言写的,这就说明这些代码已经被编译成机器码成为浏览器的一部分了,启能不比你的代码快?

小结

posted @ 2015-06-23 22:37  静逸  阅读(536)  评论(1编辑  收藏  举报