function a(){
alert('A');
a = function(){
alert('B');
};
}
function a(){
alert('A');
return function(){
alert('B');
};
}
该函数在第一次被调用后重写自己,从而避免了每次调用时重复一些不必要的的操作。这个具体怎么理解呢?重写函数前后函数执行线程不是一样吗?
阿神2017-06-12 09:31:12
举个例子,不同浏览器有的API的名称是不一样的,然后你要封装一个统一的接口,那你的代码就差不多是这样
function fn(){
if(chrome){
fn = function(){};
}else if(firefox){
fn = function(){};
}
fn();
}
習慣沉默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')
那函数式的方法,是有很多自己的优点的,这个你要去了解函数式编程。
学习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);
};
漂亮男人2017-06-12 09:31:12
简单来说
第一次运行a函数时执行的是alert('A'),第二次执行的是alert('B')。
与其说是避免重复不必要的操作,不如说是做了另外的操作。第一次运行时干了A这件事,后面运行时干的都是B这件事。