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這件事。