亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

js中匿名函數(shù)的創(chuàng)建與調(diào)用方法分析

 更新時間:2014年12月19日 16:46:36   投稿:shichen2014  
這篇文章主要介紹了js中匿名函數(shù)的創(chuàng)建與調(diào)用方法,詳細(xì)分析了匿名函數(shù)的原理與用法,以及閉包的原理分析,非常具有實用價值,需要的朋友可以參考下

本文實例分析了js中匿名函數(shù)的創(chuàng)建與調(diào)用方法。分享給大家供大家參考。具體實現(xiàn)方法如下:

匿名函數(shù)就是沒有名字的函數(shù)了,也叫閉包函數(shù)(closures),允許 臨時創(chuàng)建一個沒有指定名稱的函數(shù)。最經(jīng)常用作回調(diào)函數(shù)(callback)參數(shù)的值,很多新手朋友對于匿名函數(shù)不了解。這里就來分析一下。

function 函數(shù)名(參數(shù)列表){函數(shù)體;}

如果是創(chuàng)建匿名函數(shù),那就應(yīng)該是:
function(){函數(shù)體;}

因為是匿名函數(shù),所以一般也不會有參數(shù)傳給他。

為什么要創(chuàng)建匿名函數(shù)呢?在什么情況下會使用到匿名函數(shù)。匿名函數(shù)主要有兩種常用的場景,一是回調(diào)函數(shù),二是直接執(zhí)行函數(shù)。

回調(diào)函數(shù),像ajax的異步操作,就需要回調(diào)函數(shù)。這里就不詳解。關(guān)于直接執(zhí)行函數(shù),我看一個例子就明白了:

復(fù)制代碼 代碼如下:
<script language="javascript">
var a = "a";
(function(){
    var a="b";
    alert(a);
})();
alert(a);
</script>

在上面這段代碼中,會順序輸出兩個alert框。第一個alert框內(nèi)容為b,第二個為a。大家看到什么好處了嗎?對的,使用函數(shù)直接執(zhí)行可以限定變量的作用域,使不同腳本的相同變量可以得以共存。

下面,我們先初步了解一下和匿名函數(shù)相關(guān)的概念。

函數(shù)聲明(function 語句),要使用一個函數(shù),我們就得首先聲明它的存在。而我們最常用的方式就是使用function 語句來定義一個函數(shù),如:

復(fù)制代碼 代碼如下:
function abc(){
// code to process
}
function abc(){ // code to process }

當(dāng)然,你的函數(shù)也可以是帶參數(shù)的,甚至是帶返回值的。

復(fù)制代碼 代碼如下:
view plaincopy to clipboardprint?
function abc(x,y){
return x+y;
}
function abc(x,y){ return x+y; }

但是,無論你怎么去定義你的函數(shù),JS 解釋器都會把它翻譯成一個Function 對象。例如,你在定義上面的其中一個例子的函數(shù)號,再輸入如下代碼:

復(fù)制代碼 代碼如下:
alert(typeof abc);// "function"

你的瀏覽器就會彈出提示框,提示你abc 是一個Function 對象。那么Function 對象究竟是什么呢?

Function 對象

Function 對象是JavaScript 里面的固有對象,所有的函數(shù)實際上都是一個Function 對象。我們先看看,F(xiàn)unction 對象能不能直接運用構(gòu)造函數(shù)創(chuàng)建一個新的函數(shù)呢?答案是肯定的。例如:

復(fù)制代碼 代碼如下:
var abc = new Function("x","y","return x*y;");
alert(abc(2,3)); // "6"

相信大家現(xiàn)在對如何聲明一個函數(shù)應(yīng)該是有所了解了。那么什么才是匿名函數(shù)呢?

聲明匿名函數(shù)

顧名思義,匿名函數(shù)就是沒有實際名字的函數(shù)。例如,我們把上面的例子中,函數(shù)的名字去掉,再判斷一下他是不是一個函數(shù):

復(fù)制代碼 代碼如下:
alert(typeof function(){});// "function"
alert(typeof function(x,y){return x+y;});// "function"
alert(typeof new Function("x","y","return x*y;"))// "function"
alert(typeof function(){});// "function"
alert(typeof function(x,y){return x+y;});// "function"
alert(typeof new Function("x","y","return x*y;"))// "function"

我們可以很容易地看到,它們?nèi)际荈unction 對象,換言之,他們都是函數(shù),但是他們都有一個特點—— 沒有名字。所以我們把他們稱作“ 匿名函數(shù)” 。然而,正因為他們沒有“ 名字” ,我們也沒有辦法找到他們。這就引申了如何去調(diào)用一個匿名函數(shù)的問題了。

匿名函數(shù)的調(diào)用

要調(diào)用一個函數(shù),我們必須要有方法定位它,引用它。所以,我們會需要幫它找一個名字。例如:

復(fù)制代碼 代碼如下:
var abc=function(x,y){
return x+y;
}
alert(abc(2,3)); // "5"

上面的操作其實就等于換個方式去定義函數(shù),這種用法是我們比較頻繁遇到的。例如我們在設(shè)定一個DOM 元素事件處理函數(shù)的時候,我們通常都不會為他們定名字,而是賦予它的對應(yīng)事件引用一個匿名函數(shù)。

對匿名函數(shù)的調(diào)用其實還有一種做法,也就是我們看到的jQuery 片段—— 使用() 將匿名函數(shù)括起來,然后后面再加一對小括號(包含參數(shù)列表)。我們再看一下以下例子:

復(fù)制代碼 代碼如下:
alert((function(x,y){return x+y;})(2,3));// "5"
alert((new Function("x","y","return x*y;"))(2,3));// "6"

很多人或許會奇怪,為什么這種方法能成功調(diào)用呢?覺得這個應(yīng)用奇怪的人就看一下我以下這段解釋吧。

大家知道小括號的作用嗎?小括號能把我們的表達(dá)式組合分塊,并且每一塊,也就是每一對小括號,都有一個返回值。這個返回值實際上也就是小括號中表達(dá)式的返回值。所以,當(dāng)我們用一對小括號把匿名函數(shù)括起來的時候,實際上小括號對返回的,就是一個匿名函數(shù)的Function 對象。因此,小括號對加上匿名函數(shù)就如同有名字的函數(shù)般被我們?nèi)〉盟囊梦恢昧?。所以如果在這個引用變量后面再加上參數(shù)列表,就會實現(xiàn)普通函數(shù)的調(diào)用形式。

不知道以上的文字表述大家能不能看明白,如果還是理解不了的話,再看一下以下的代碼試試吧。

復(fù)制代碼 代碼如下:
var abc=function(x,y){return x+y;};// 把匿名函數(shù)對象賦給abc
// abc 的constructor 就和匿名函數(shù)的constructor 一樣了。也就是說,兩個函數(shù)的實現(xiàn)是一樣的。
alert((abc).constructor==(function(x,y){return x+y;}).constructor);

PS :constructor 是指創(chuàng)建對象的函數(shù)。也就是函數(shù)對象所代表的函數(shù)體。
總之,將其(被小括號包含的匿名函數(shù))理解為括號表達(dá)式返回的函數(shù)對象,然后就可以對這個函數(shù)對象作正常的參數(shù)列表調(diào)用了。(前面這里犯了個錯誤,只有函數(shù)表達(dá)式還是不能直接調(diào)用函數(shù)的,去掉匿名函數(shù)括號必須要伴隨將表達(dá)式賦值。也就是(function(){alert(1)})() 應(yīng)該是與 a=function(){alert(1)}() 等價,不能連a= 都去掉。)

閉包

閉包是什么?閉包是指某種程序語言中的代碼塊允許一級函數(shù)存在并且在一級函數(shù)中所定義的自由變量能不被釋放,直到一級函數(shù)被釋放前,一級函數(shù)外也能應(yīng)用這些未釋放的自由變量。

怎樣?看得一頭冒汗吧…… 沒事,我也是(雖然是我是了解的,只是表達(dá)能力的問題)。讓我們換個更加簡單的方法說明:閉包,其實是一種語言特性,它是指的是程序設(shè)計語言中,允許將函數(shù)看作對象,然后能像在對象中的操作般在函數(shù)中定義實例(局部)變量,而這些變量能在函數(shù)中保存到函數(shù)的實例對象銷毀為止,其它代碼塊能通過某種方式獲取這些實例(局部)變量的值并進(jìn)行應(yīng)用擴展。

不知道這么再解釋后會否更加清晰,如果還是不明白,那么我們再簡化一下:閉包,其實就是指程序語言中能讓代碼調(diào)用已運行的函數(shù)中所定義的局部變量。

現(xiàn)在我們看一個例子:

復(fù)制代碼 代碼如下:
var abc=function(y){
var x=y;// 這個是局部變量
return function(){
alert(x++);// 就是這里調(diào)用了閉包特性中的一級函數(shù)局部變量的x ,并對它進(jìn)行操作
alert(y--);// 引用的參數(shù)變量也是自由變量
}}(5);// 初始化
abc();// "5" "5"
abc();// "6" "4"
abc();// "7" "3"
alert(x);// 報錯!“x” 未定義!

看到這里,你能判斷究竟jQuery 的那個代碼片段是否閉包了嗎?

以我的理解來說吧。是否應(yīng)用了閉包特性,必須確定該段代碼有沒有最重要的要素:未銷毀的局部變量。那么很顯然,沒有任何實現(xiàn)的匿名函數(shù)不可能應(yīng)用了閉包特性。但如果匿名函數(shù)里面有實現(xiàn)呢?那也還得確定它的實現(xiàn)中有沒有 用到那些未銷毀的局部變量。所以如果問你那個開篇中的jQuery 代碼片段是應(yīng)用了JS 里的什么特性?那么它只是匿名函數(shù)與匿名函數(shù)的調(diào)用而已。但是,它 隱含了閉包的特性,并且隨時可以實現(xiàn)閉包應(yīng)用。

最常見的用法:

復(fù)制代碼 代碼如下:
(function() {
alert('water');
})();

當(dāng)然也可以帶參數(shù):
復(fù)制代碼 代碼如下:
(function(o) {
alert(o);
})('water');

想用匿名函數(shù)的鏈?zhǔn)秸{(diào)用?很簡單:
復(fù)制代碼 代碼如下:
(function(o) {
alert(o);
return arguments.callee;
})('water')('down');

常見的匿名函數(shù)都知道了,看看不常見的:
復(fù)制代碼 代碼如下:
~(function(){
alert('water');
})();//寫法有點酷~
 
void function(){
alert('water');
}();//據(jù)說效率最高~
 
+function(){
alert('water');
}();
 
-function(){
alert('water');
}();
 
~function(){
alert('water');
}();
 
!function(){
alert('water');
}();
 
(function(){
alert('water');
}());//有點強制執(zhí)行的味道~

希望本文所述對大家的javascript程序設(shè)計有所幫助。

相關(guān)文章

  • javascript htmlencode函數(shù)(ff兼容版) 主要是編輯器中反轉(zhuǎn)html代碼

    javascript htmlencode函數(shù)(ff兼容版) 主要是編輯器中反轉(zhuǎn)html代碼

    非常不錯的htmlencode 方法,比用正則實現(xiàn)的更好,而且效率高,推薦使用第一種方法。
    2009-06-06
  • 原生js實現(xiàn)簡單輪播圖

    原生js實現(xiàn)簡單輪播圖

    這篇文章主要為大家詳細(xì)介紹了原生js實現(xiàn)簡單輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 如何在JavaScript中謹(jǐn)慎使用代碼注釋

    如何在JavaScript中謹(jǐn)慎使用代碼注釋

    這篇文章主要介紹了如何在JavaScript中謹(jǐn)慎使用代碼注釋,必要的注釋可以闡明實現(xiàn)細(xì)節(jié)和設(shè)計意圖,以此節(jié)約自己和別人的時間。 然而很多時候注釋起的作用卻適得其反,,需要的朋友可以參考下
    2019-06-06
  • 淺析JavaScript中的同名標(biāo)識符優(yōu)先級

    淺析JavaScript中的同名標(biāo)識符優(yōu)先級

    這篇文章主要介紹了JavaScript中的同名標(biāo)識符優(yōu)先級。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-12-12
  • JavaScript中淺講ajax圖文詳解

    JavaScript中淺講ajax圖文詳解

    ajax對于各位來說,應(yīng)該都不陌生,正因為ajax的產(chǎn)生,導(dǎo)致前臺頁面和服務(wù)器之間的數(shù)據(jù)傳輸變得非常容易,同時還可以實現(xiàn)頁面的局部刷新。本文圖文并茂給大家介紹了js中ajax知識,需要的朋友一起學(xué)習(xí)吧
    2016-11-11
  • TypeScript中的方法重載詳解

    TypeScript中的方法重載詳解

    這篇文章主要給大家介紹了關(guān)于TypeScript中方法重載的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用TypeScript具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 微信小程序如何調(diào)用json數(shù)據(jù)接口并解析

    微信小程序如何調(diào)用json數(shù)據(jù)接口并解析

    這篇文章主要介紹了微信小程序如何調(diào)用json數(shù)據(jù)接口并解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-06-06
  • 原生JS簡單實現(xiàn)ajax的方法示例

    原生JS簡單實現(xiàn)ajax的方法示例

    這篇文章主要介紹了原生JS簡單實現(xiàn)ajax的方法,結(jié)合實例形式分析了ajax的實現(xiàn)步驟與相關(guān)使用技巧,需要的朋友可以參考下
    2016-11-11
  • 對Web開發(fā)中前端框架與前端類庫的一些思考

    對Web開發(fā)中前端框架與前端類庫的一些思考

    這篇文章主要介紹了對Web開發(fā)中前端框架與前端類庫的一些思考,本文講解了前端框架的理解誤區(qū)、前端框架與前端類庫的區(qū)別、前端MVC框架思想等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • 跨域請求兩種方法 jsonp和cors的實現(xiàn)

    跨域請求兩種方法 jsonp和cors的實現(xiàn)

    這篇文章主要介紹了跨域請求兩種方法 jsonp和cors的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論