Heim  >  Fragen und Antworten  >  Hauptteil

Vorteile überschreibender Funktionen?

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

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

Diese Funktion schreibt sich nach dem ersten Aufruf neu und vermeidet so unnötige Wiederholungen von Vorgängen bei jedem Aufruf. Wie ist das konkret zu verstehen? Ist der Funktionsausführungsthread vor und nach dem Umschreiben der Funktion nicht derselbe?

女神的闺蜜爱上我女神的闺蜜爱上我2708 Tage vor747

Antworte allen(4)Ich werde antworten

  • 阿神

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

    举个例子,不同浏览器有的API的名称是不一样的,然后你要封装一个统一的接口,那你的代码就差不多是这样

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

    Antwort
    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')

    那函数式的方法,是有很多自己的优点的,这个你要去了解函数式编程。

    Antwort
    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);
    };

    Antwort
    0
  • 漂亮男人

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

    简单来说

    第一次运行a函数时执行的是alert('A'),第二次执行的是alert('B')。

    与其说是避免重复不必要的操作,不如说是做了另外的操作。第一次运行时干了A这件事,后面运行时干的都是B这件事。

    Antwort
    0
  • StornierenAntwort