亚洲欧美色图区_全黄h全肉短篇|HD中文字幕在线播放,美国禁忌l一4电影,国产一区二区在线观看视频,痴汉电影院侵犯中文字幕

    電話

    0411-39943997

仟億科技
客服中心
  • 電話
  • 電話咨詢:0411-39943997
  • 手機(jī)
  • 手機(jī)咨詢:15840979770
    手機(jī)咨詢:13889672791
網(wǎng)絡(luò)營銷 >更多
您現(xiàn)在的位置:首頁 > 新聞中心 > 常見問題

JavaScript需要Blocks

作者:billionnet 發(fā)布于:2012/5/4 18:15:49 點(diǎn)擊量:

 

常常會遇到有人將Ruby的區(qū)塊(Blocks)看作相當(dāng)于JavaScript的“firstclassfunctions”的誤解。由于傳遞功能,尤其是當(dāng)你可以創(chuàng)建匿名的傳遞功能,這是非常強(qiáng)大的。事實(shí)上,JavaScript和Ruby有一個機(jī)制使其自然會認(rèn)為等值。

人們在談到為什么Ruby的區(qū)塊不同于Python的函數(shù)時,通常會講到一些關(guān)于Ruby和JavaScript的匿名分享,但Python沒有。初看之下,一個Ruby區(qū)塊就是一個“匿名函數(shù)”(或俗稱一個“封裝”),正如JavaScript函數(shù)就是其中之一。

作為一個早期的Ruby/JavaScript開發(fā)者,無可否認(rèn)我也有過這樣的觀點(diǎn)分享。錯過一個重要的細(xì)節(jié),對結(jié)果會產(chǎn)生較大影響。這個原理常被稱為“Tennent’sCorrespondencePrinciple”,這條原理說:“Foragivenexpressionexpr,lambdaexprshouldbeequivalent.”這就是被稱為抽象的原則,因?yàn)檫@意味著,用“區(qū)塊”的方法很容易重構(gòu)通用代碼。例如,常見文件資源管理的情況。試想在Ruby中,F(xiàn)ile.open塊形式是不存在的,你會看到以下代碼:

 

begin

f=File.open(filename,"r")

#dosomethingwithf

ensure

f.close

end

 

在一般情況下,“區(qū)塊”代碼有著相同的開始和結(jié)束編碼、不同的內(nèi)部編碼。現(xiàn)在重構(gòu)這段代碼,你會這樣寫:

 

defread_file(filename)

f=File.open(filename,"r")

yieldf

ensure

f.close

end

 

代碼中的模式與重構(gòu)實(shí)例:

 

read_file(filename)do|f|

#dosomethingwithf

End

 

重要的是重構(gòu)之后區(qū)塊內(nèi)的代碼和以前一樣。在以下情況時,我們可以重申抽象原則的對應(yīng)原理:

 

#dosomethingwithf

 

應(yīng)相等于:

 

do

#dosomethingwith

end

 

乍一看,在Ruby和JavaScript中確實(shí)如此。例如,假設(shè)你正在使用的文件打印它的mtime。您可以輕松地重構(gòu)相當(dāng)于在JavaScript:

 

try{

//imaginaryJSfileAPI

varf=File.open(filename,"r");

sys.print(f.mtime);

}finally{

f.close();

}

 

到這里:

 

read_file(function(f){

sys.print(f.mtime);

});

 

事實(shí)上,這樣的情況往往給人錯誤的印象,Ruby和JavaScript有同樣用匿名函數(shù)重構(gòu)常用功能的能力。

不過,再來一個稍微復(fù)雜一些的例子。我們首先在Ruby中編寫一個簡單的類,計算文件的mtime和檢索它的正文:

 

classFileInfo

definitialize(filename)

@name=filename

end

#calculatetheFile's+mtime+

defmtime

f=File.open(@name,"r")

mtime=mtime_for(f)

return"tooold"ifmtime<(Time.now-1000)

puts"recent!"

mtime

ensure

f.close

end

#retrievethatfile's+body+

defbody

f=File.open(@name,"r")

f.read

ensure

f.close

end

#ahelpermethodtoretrievethemtimeofafile

defmtime_for(f)

File.mtime(f)

end

end

 

我們可以用區(qū)塊很容易地重構(gòu)這段代碼:

 

classFileInfo

definitialize(filename)

@name=filename

end

#refactorthecommonfilemanagementcodeintoamethod

#thattakesablock

defmtime

with_filedo|f|

mtime=mtime_for(f)

return"tooold"ifmtime<(Time.now-1000)

puts"recent!"

mtime

end

end

defbody

with_file{|f|f.read}

end

defmtime_for(f)

File.mtime(f)

end

private

#thismethodopensafile,callsablockwithit,and

#ensuresthatthefileisclosedoncetheblockhas

#finishedexecuting.

defwith_file

f=File.open(@name,"r")

yieldf

ensure

f.close

end

end

 

同樣地,需要注意的重點(diǎn)是,我們構(gòu)建區(qū)塊卻并不改變它的內(nèi)部代碼。但不幸的是,這個相同情況的例子無法在JavaScript中正常工作。讓我們在JavaScript中來寫等同的FileInfo類:

 

//constructorfortheFileInfoclass

FileInfo=function(filename){

this.name=filename;

};

FileInfo.prototype={

//retrievethefile'smtime

mtime:function(){

try{

varf=File.open(this.name,"r");

varmtime=this.mtimeFor(f);

if(mtime

return"tooold";

}

sys.print(mtime);

}finally{

f.close();

}

},

//retrievethefile'sbody

body:function(){

try{

varf=File.open(this.name,"r");

returnf.read();

}finally{

f.close();

}

},

//ahelpermethodtoretrievethemtimeofafile

mtimeFor:function(f){

returnFile.mtime(f);

}

};

 

如果我們試圖將其轉(zhuǎn)換成一個接受重復(fù)函數(shù)的代碼,那mtime方法看起來將是:在這里有兩個非常普遍的問題。首先是上下文改變了。我們可以通過允許綁定第二參數(shù),但這意味著每次重構(gòu)時需要確認(rèn)并通過一個變量傳遞參數(shù),就是說這一情況會在因?yàn)槿狈avaScript信任組件時而出現(xiàn)。

 

function() {

// refactor the common file management code into a method

// that takes a block

this.withFile(function(f) {

var mtime = this.mtimeFor(f);

if (mtime < new Date() - 1000) {

return "too old";

}

sys.print(mtime);

});

}

 

這很煩人,更棘手的還在于,它是從內(nèi)部返回結(jié)果而不是從函數(shù)外部。這個真實(shí)的結(jié)果違反了抽象原則中的對應(yīng)原理。相反,在函數(shù)中用區(qū)塊方法毫不費(fèi)力地重構(gòu)具有相同開始和結(jié)束的代碼時,JavaScript庫作者需要考慮使用者對API處理嵌套函數(shù)時進(jìn)行的一些操作。作為一個JavaScript庫資源的編寫者和使用者看來,這提供了一個很好的基于區(qū)塊的API。

迭代和回調(diào)

值得注意的是,區(qū)塊lambda函數(shù)接受功能調(diào)用的案例包括迭代器、同步與互斥、資源管理(如區(qū)塊形式的File.open)。

使用函數(shù)作為回調(diào)時,關(guān)鍵字不再有意義。從一個已經(jīng)返回的函數(shù)返回是什么意思?在這種情況下,通常涉及回調(diào)函數(shù)lambda表達(dá)式做出了很大的意義。在我看來,這解釋了為什么JavaScript事件觸發(fā)代碼,涉及了大量的回調(diào)。

由于這些問題,ECMA工作組負(fù)責(zé)的ECMAScript,TC39,正在考慮加入塊lambda表達(dá)式語言。這將意味著,上面的例子可重構(gòu):

 

FileInfo=function(name){

this.name=name;

};

FileInfo.prototype={

mtime:function(){

//usetheproposedblocksyntax,`{|args|}`.

this.withFile{|f|

//inblocklambdas,+this+isunchanged

varmtime=this.mtimeFor(f);

if(mtime

//blocklambdasreturnfromtheirnearestfunction

return"tooold";

}

sys.print(mtime);

}

},

body:function(){

this.withFile{|f|f.read();}

},

mtimeFor:function(f){

returnFile.mtime(f);

},

withFile:function(block){

try{

varf=File.open(this.name,"r");

block(f);

}finally{

f.close();

}

}

};

 

TC39并沒有實(shí)質(zhì)性改變這個例子,并且要注意區(qū)塊lambda表達(dá)式自動返回他們的最后一個語句。

經(jīng)驗(yàn)顯示,Smalltalk和Ruby不需要理解一種語言可怕的對應(yīng)原理,滿足它獲得自己想要的結(jié)果。“迭代”概念并不內(nèi)置到語言,而是被自然塊定義的結(jié)果。這使得Ruby以及其他常用語言的開發(fā)者可建立自定義的豐富、內(nèi)置的迭代設(shè)置。作為一個JavaScript實(shí)踐者,我經(jīng)常碰到的情況是,用一個for循環(huán)比使用forEach更為簡單明了。

業(yè)界人士觀點(diǎn)

munificent:Inordertohavealanguagewithreturn(andpossiblysuperandothersimilarkeywords)thatsatisfiesthecorrespondenceprinciple,thelanguagemust,likeRubyandSmalltalkbeforeit,haveafunctionlambdaandablocklambda.Keywordslikereturnalwaysreturnfromthefunctionlambda,eveninsideofblocklambdasnestedinside.Incaseyouwanttogetyourgoogle/wikipediaon,whatKatzistalkingabouthereisa"non-localreturn".

更多評論詳細(xì)請點(diǎn)擊這里>>

ericbb:Alternateformulationwithhypotheticalshift/reset(delimitedcontinuationsupport)andblocksthatreturnthesamewayfunctionsdo:

 

mtime:function(){

returnreset{

varmtime=shift(succeed){

this.withFile({|f|

varmtime=this.mtimeFor(f);

if(mtime

return"tooold";

}

returnsucceed(mtime);

});

};

sys.print(mtime);

return"youngenough";

};

},

Thesucceedfunctionisafirstclass,indefinite-extentfunctionequivalentto:

 

 

function(mtime){

sys.print(mtime);

return"youngenough";

}

 

  



分享到:


Copyright@ 2011-2016 版權(quán)所有:大連千億科技有限公司 遼ICP備11013762-3號   google網(wǎng)站地圖   百度網(wǎng)站地圖   網(wǎng)站地圖

公司地址:大連市沙河口區(qū)中山路692號辰熙星海國際2317 客服電話:0411-39943997 QQ:2088827823 37482752

法律聲明:未經(jīng)許可,任何模仿本站模板、轉(zhuǎn)載本站內(nèi)容等行為者,本站保留追究其法律責(zé)任的權(quán)利! 隱私權(quán)政策聲明