## 常規優化
> * 傳遞方法取代方法字符串
>
>
>
> 一些方法例如`setTimeout()`、`setInterval()`,接受`字符串`或者`方法實例`作為參數。直接傳遞方法對象作為參數來避免對字符串的二次解析。
>
>
> * 傳遞方法
>
>
>
> ~~~
> setTimeout(test, 1);
> ~~~
>
>
> * 傳遞方法字符串
>
>
>
> ~~~
> setTimeout('test()', 1);
> ~~~
>
>
> * 使用原始操作代替方法調用
>
>
>
> 方法調用一般封裝了原始操作,在性能要求高的邏輯中,可以使用原始操作代替方法調用來提高性能。
>
>
> * 原始操作
>
>
>
> ~~~
> var min = a<b?a:b;
> ~~~
>
>
> * 方法實例
>
>
>
> ~~~
> var min = Math.min(a, b);
> ~~~
>
>
> * 定時器
>
>
>
> 如果針對的是不斷運行的代碼,不應該使用`setTimeout`,而應該是用`setInterval`。`setTimeout`每次要重新設置一個定時器。
>
>
> * 避免雙重解釋
>
>
>
> 當`JAVASCRIPT`代碼想解析`JAVASCRIPT`代碼時就會存在雙重解釋懲罰,雙重解釋一般在使用`eval`函數、`new Function`構造函數和`setTimeout`傳一個字符串時等情況下會遇到,如。
>
>
>
> ~~~
> eval("alert('hello world');");
> var sayHi = new Function("alert('hello world');");
> setTimeout("alert('hello world');", 100);
> ~~~
>
>
>
> 上述`alert('hello world');`語句包含在字符串中,即在JS代碼運行的同時必須新啟運一個解析器來解析新的代碼,而實例化一個新的解析器有很大的性能損耗。 我們看看下面的例子:
>
>
>
> ~~~
> var sum, num1 = 1, num2 = 2;
> /**效率低**/
> for(var i = 0; i < 10000; i++){
> var func = new Function("sum+=num1;num1+=num2;num2++;");
> func();
> //eval("sum+=num1;num1+=num2;num2++;");
> }
> /**效率高**/
> for(var i = 0; i < 10000; i++){
> sum+=num1;
> num1+=num2;
> num2++;
> }
> ~~~
>
>
>
> 第一種情況我們是使用了new Function來進行雙重解釋,而第二種是避免了雙重解釋。
>
>
> * 原生方法更快
>
>
> * 只要有可能,使用原生方法而不是自已用JS重寫。原生方法是用諸如C/C++之類的編譯型語言寫出來的,要比JS的快多了。
> * 最小化語句數
>
>
>
> JS代碼中的語句數量也會影響所執行的操作的速度,完成多個操作的單個語句要比完成單個操作的多個語句塊快。故要找出可以組合在一起的語句,以減來整體的執行時間。這里列舉幾種模式
>
>
> * 多個變量聲明
>
>
>
> ~~~
> /**不提倡**/
> var i = 1;
> var j = "hello";
> var arr = [1,2,3];
> var now = new Date();
> /**提倡**/
> var i = 1,
> j = "hello",
> arr = [1,2,3],
> now = new Date();
> ~~~
>
>
> * 插入迭代值
>
>
>
> ~~~
> /**不提倡**/
> var name = values[i];
> i++;
> /**提倡**/
> var name = values[i++];
> ~~~
>
>
> * 使用數組和對象字面量,避免使用構造函數Array(),Object()
>
>
>
> ~~~
> /**不提倡**/
> var a = new Array();
> a[0] = 1;
> a[1] = "hello";
> a[2] = 45;
> var o = new Obejct();
> o.name = "bill";
> o.age = 13;
> /**提倡**/
> var a = [1, "hello", 45];
> var o = {
> name : "bill",
> age : 13
> };
> ~~~
>
>
> * 避免使用屬性訪問方法
>
>
> * JavaScript不需要屬性訪問方法,因為所有的屬性都是外部可見的。
> * 添加屬性訪問方法只是增加了一層重定向 ,對于訪問控制沒有意義。
>
>
>
> 使用屬性訪問方法示例
>
>
>
> ~~~
> function Car() {
> this .m_tireSize = 17;
> this .m_maxSpeed = 250;
> this .GetTireSize = Car_get_tireSize;
> this .SetTireSize = Car_put_tireSize;
> }
>
> function Car_get_tireSize() {
> return this .m_tireSize;
> }
>
> function Car_put_tireSize(value) {
> this .m_tireSize = value;
> }
> var ooCar = new Car();
> var iTireSize = ooCar.GetTireSize();
> ooCar.SetTireSize(iTireSize + 1);
> ~~~
>
>
>
> 直接訪問屬性示例
>
>
>
> ~~~
> function Car() {
> this .m_tireSize = 17;
> this .m_maxSpeed = 250;
> }
> var perfCar = new Car();
> var iTireSize = perfCar.m_tireSize;
> perfCar.m_tireSize = iTireSize + 1;
> ~~~
>
>
> * 減少使用元素位置操作
>
>
> * 一般瀏覽器都會使用增量reflow的方式將需要reflow的操作積累到一定程度然后再一起觸發,但是如果腳本中要獲取以下屬性,那么積累的reflow將會馬上執行,已得到準確的位置信息。
>
>
>
> ~~~
> offsetLeft
> offsetTop
> offsetHeight
> offsetWidth
> scrollTop/Left/Width/Height
> clientTop/Left/Width/Height
> getComputedStyle()
> ~~~