function a(){ alert('A'); a = function(){ alert('B'); }; } function a(){ alert('A'); return function(){ alert('B'); }; }
该函数在第一次被调用后重写自己,从而避免了每次调用时重复一些不必要的的操作。这个具体怎么理解呢?重写函数前后函数执行线程不是一样吗?
举个例子,不同浏览器有的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')
那函数式的方法,是有很多自己的优点的,这个你要去了解函数式编程。
楼上那个浏览器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这件事。
举个例子,不同浏览器有的API的名称是不一样的,然后你要封装一个统一的接口,那你的代码就差不多是这样
在不使用额外变量的情况下,不使用if-else的情况下,区分了一个布尔型的状态。
比如有些行为,在初始化和未初始化的情况下逻辑不一样,那么可以这么写:
这里很糟糕的,引入了全局变量,那可以将这个变量封装在成一个内部状态,可以这么写:
如果使用题主说的方法的话:
另外,这样的写法感觉很函数式(个人对函数式了解不多,不敢绝对)。那么这里就是编程范式的问题了。
感受一下下面三种不同的写法:
面向过程:
面向对象:
函数式:
那函数式的方法,是有很多自己的优点的,这个你要去了解函数式编程。
楼上那个浏览器API的例子是个很好的例子,总的来说,函数重写更多的是为了规避某些不必要的操作,从而达到优化代码性能的目的, 我再给你举个更常用的:
简单来说
第一次运行a函数时执行的是alert('A'),第二次执行的是alert('B')。
与其说是避免重复不必要的操作,不如说是做了另外的操作。第一次运行时干了A这件事,后面运行时干的都是B这件事。