javascript - 重写函数的优点?
女神的闺蜜爱上我
女神的闺蜜爱上我 2017-06-12 09:29:12
0
4
786
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这件事。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板