JS程序設計高級技巧

1、高級函數javascript

  1. 安全類型檢測java

    Object.protitype.toString.call(value)
  2. 做用域安全的構造函數數組

    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);
        }
    }
    // 若是你使用構造函數竊取模式的繼承且不使用原型鏈,這個繼承極可能被破壞
    function Teacher (name, age, job, salary) {
        // this指向非Peroson 返回新的實例,構造函數中的this屬性並未增加
        Person.call(this, name, age, job); 
        this.salary = salary;
    }
    // 解決這個問題的方法是,Teacher.prototype = new Person(),此時一個Teacher實例也是一個Person實例
  3. 惰性載入函數
    在函數被調用的時候再處理函數,在第一次調用的過程當中,該函數會被覆蓋爲另外一個按合適方式執行的函數安全

    function createXHR () {
        if (typeof XMLHttpRequest != 'undefined) {
            createXHR  = function () {
                return new XMLHttpRequest ();
            }
        } else if (typeof ActiveXObject != 'undefined') {
            createXHR = function () {
                if (typeof arguments.callee.activeString != 'string') {
                    //...
                }
            }
        } else {
            createXHR  = function () {
                // ...
            }
        }
        return createXHR();
    }

    在聲明的時候就指定適當的函數,利用匿名函數自運行,return一個合適的函數閉包

  4. 函數綁定
    一個簡單的bind函數app

    function bind(fn, context){
        return function() {
            return fn.apply(context, arguments)
        }
    }
  5. 函數柯里化
    函數的柯里化的基本方法和函數綁定是同樣的,使用一個閉包返回一個函數,區別是,當函數被調用時,還須要傳遞一些參數
    柯里化函數動態建立步驟:調用另外一個函數併爲它傳入要柯里化的函數和必要參數函數

    function curry(fn){
        var args = Array.prototype.slice.call(arguments, 1);
        return function () {
            var innerArgs = Array.prototype.slice.call(arguments);
            var finalArgs = args.concat(innerArgs);
            return fn.apply(null, finalArgs)
        }
    }
  6. es5中的防篡改對象
    不可擴展對象this

    Objcect.preventExtensions(obj)   // 設置對象屬性是否能夠擴展
    Objcect.isExtensible(obj)         // 返回值爲bool值,true即該對象能夠擴展,false爲不可擴展

    密封的對象
    密封對象不可擴展,並且已有成員的[ [ Configurable ] ]特性將被設置爲false,這就意味着不能刪除屬性和方法es5

    Object.seal(obj)     // 設置對象是不是密封
    Object.isSealed    // 返回值爲bool值,true即該對象已經密封,false爲沒有密封

    凍結對象
    凍結的對象既不能夠擴展,又是密封的prototype

    Object.freeze(obj)         // 設置對象是否凍結
    Objcet.isForzen(obj)    // 返回值爲bool值,true即該對象已經凍結,false爲沒有凍結
  7. 高級定時器
    除了主Javascript執行進程外,還有一個須要在進程下次一空閒的時執行的代碼隊列。隨着頁面在其生命週期中的推移,代碼會按照執行順序添加到隊列。
    關於定時器要記住的最重要的事情是:指定的時間間隔表示什麼時候將定時器的代碼添加到隊列,而不是什麼時候實際執行代碼。
    a.重複的定時器

    使用setInterval()建立的定時器確保了定時器代碼規則地插入隊列中,這個方式的問題在於定時器代碼可能在代碼再次被添加到隊列以前尚未完成執行,結果致使定時器代碼連續運行好幾回,而之間沒有任何停頓,javascript引擎在使用setInterval時,僅當沒有該定時器的代碼是纔將定時器的代碼添加到隊列中,可是這樣會致使一、某些間隔時間被跳過。

    b.多個定時器之間的執行間隔會比預期的小

    // 解決辦法
    setTimeout(function () {
        //處理中
        setTimeout(arguments.callee, interval)
    }, interval)
  8. 數組分塊

    function chunk(array, process, context) {
        setTimeout( function() {
            var Item = array.shift();
            process(item)
            if (array.length > 0) {
                setTimeout(arguments.callee, 100)
            }
        }, 100)
    }
  9. 函數節流

    var processor = {
        timeoutId = null,
        // 實際進行處理的方法
        performProcessing: function() {
        // 實際執行的代碼
    },
    // 初始處理調用的方法
    process: function () {
        clearTimeout(this.timeouId);
        var that = this;
        this.timeoutId = setTimeout(function () {
            that.performProcessing();
        }, 100)
        }
    }
相關文章
相關標籤/搜索