javascript - 重寫函數的優點?
女神的闺蜜爱上我
女神的闺蜜爱上我 2017-06-12 09:29:12
0
4
758
function a(){
    alert('A');
    a = function(){
        alert('B');
    };
}

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

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

女神的闺蜜爱上我
女神的闺蜜爱上我

全部回覆(4)
阿神

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

function fn(){
    if(chrome){
        fn = function(){};
    }else if(firefox){
        fn = function(){};
    }
    fn();
}
習慣沉默

在不使用額外變數的情況下,不使用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')

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

学习ing

樓上那個瀏覽器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);
};
漂亮男人

簡單來說

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

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

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板