首頁  >  問答  >  主體

javascript - 重寫函數的優點?

function a(){
    alert('A');
    a = function(){
        alert('B');
    };
}

function a(){
    alert('A');
    return function(){
        alert('B');
    };
}

該函數在第一次被呼叫後重寫自己,從而避免了每次呼叫時重複一些不必要的操作。這個具體怎麼理解呢?重寫函數前後函數執行緒不是一樣嗎?

女神的闺蜜爱上我女神的闺蜜爱上我2657 天前701

全部回覆(4)我來回復

  • 阿神

    阿神2017-06-12 09:31:12

    舉個例子,不同瀏覽器有的API的名稱是不一樣的,然後你要封裝一個統一的接口,那你的程式碼就差不多是這樣

    function fn(){
        if(chrome){
            fn = function(){};
        }else if(firefox){
            fn = function(){};
        }
        fn();
    }

    回覆
    0
  • 習慣沉默

    習慣沉默2017-06-12 09:31:12

    在不使用額外變數的情況下,不使用if-else的情況下,區分了一個布林型的狀態。
    例如有些行為,在初始化和未初始化的情況下邏輯不一樣,那麼可以這麼寫:

    var initiated = false
    function action () {
        if (initiated) {
            // action 1
        } else {
            // action 2
            initiated = true
        }
    }

    這裡很糟糕的,引入了全域變量,那可以將這個變數封裝在成一個內部狀態,可以這麼寫:

    class Action {
        constructor () {
            this.initiated = false
            this._init()
        }
        _init () {
            // action 2
            this.initiated = true
        }
        action () {
            // action 1
        }
    }
    
    var myAction = new Action()
    myAction.action()

    如果使用題主所說的方法的話:

    function action () {
        // action 2
        return function () {
            // action 1
        }
    }
    
    var myAction = action()
    myAction()

    另外,這樣的寫法感覺很函數式(個人對函數式了解不多,不敢絕對)。那麼這裡就是程式設計範式的問題了。
    感受一下以下三種不同的寫法:

    面向過程:

    function logger (type, content) {
        var now = new Date()
        if (type === 'debug') {
            console.log('DEBUG::' + now + ' ' + content)
        } else if (type === 'info') {
            console.log('INFO::' + now + ' ' + content)
        }
    }
    
    logger('debug', 'xxx')
    logger('info', 'xxx')

    面向對象:

    class Logger {
        _now () {
            return new Date()
        }
        debug (content) {
            console.log('DEBUG::' + this._now() + ' ' + content)
        }
        info (content) {
            var now = new Date()
            console.log('INFO::' + this._now() + ' ' + content)
        }
    }
    
    var logger = new Logger()
    logger.debug('xxx')
    logger.info('xxx')

    函數式:

    function logger (type) {
        var prefix = ''
        if (type === 'debug') {
            prefix = 'DEBUG'
        } else if (type === 'info') {
            prefix = 'INFO'
        }
        
        return function (content) {
            var now = new Date()
            console.log(prefix + '::' + now + ' ' + content)
        }
    }
    
    var debugLogger = logger('debug')
    var infoLogger = logger('info')
    
    debugLogger('xxxx')
    infoLogger('xxxx')

    那函數式的方法,是有很多自己的優點的,這個你要去了解函數式程式設計。

    回覆
    0
  • 学习ing

    学习ing2017-06-12 09:31:12

    樓上那個瀏覽器API的例子是個很好的例子,總的來說,函數重寫更多的是為了規避某些不必要的操作,從而達到優化代碼性能的目的, 我再給你舉個更常用的:

    //就比如说我们经常要通过addEventListener来绑定事件,但是在某些老版本浏览器可能用的是attachEvent和on,这时我们可以:
    var bindEvent = function(target,event,handle){
        //下面就是针对性的重写
        if(target.addEventListener){
            bindEvent = function(target,event,handle){
                target.addEventListener(event,handle,false);
            };
        } else if( target.attachEvent ){
            bindEvent = function(target,event,handle){
                target.attachEvent("on"+event,handle);
            };
        } else {
            bindEvent = function(target,event,handle){
                target["on"+event] = handle;
            };
        }
        bindEvent(target,event,handle);
    };

    回覆
    0
  • 漂亮男人

    漂亮男人2017-06-12 09:31:12

    簡單來說

    第一次執行a函數時執行的是alert('A'),第二次執行的是alert('B')。

    與其說是避免重複不必要的操作,不如說是做了另外的操作。第一次運行時乾了A這件事,後面運行時幹的都是B這件事。

    回覆
    0
  • 取消回覆