首页  >  问答  >  正文

javascript - 重写函数的优点?

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

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

该函数在第一次被调用后重写自己,从而避免了每次调用时重复一些不必要的的操作。这个具体怎么理解呢?重写函数前后函数执行线程不是一样吗?

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

全部回复(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
  • 取消回复