整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JavaScript之匿名函數(shù)

          avaScript中除了自定義函數(shù)之外,還有匿名函數(shù)?什么是匿名函數(shù)?

          1. 匿名函數(shù):沒有函數(shù)名稱的函數(shù)。

          如:定義一個匿名函數(shù),打印5個星星。

          <script>

          function (){ //沒有函數(shù)名稱

          for(var i=0;i<5;i++){

          document.write("*");

          }

          }

          </script>

          2. 調(diào)用匿名函數(shù)有2種方法:

          (1) 通過變量名調(diào)用匿名函數(shù)可以理解為將整個匿名函數(shù)瀆職給一個變量

          然后在body標(biāo)簽中,定義一個按鈕:

          (2) 事件名調(diào)用匿名函數(shù)

          同樣在在body標(biāo)簽中,先定義一個按鈕:注意在input標(biāo)簽中我們不通過onclick來調(diào)用匿名函數(shù)

          然后我們通過2個事件調(diào)用2個匿名函數(shù):

          注意:window.onload:頁面加載時觸發(fā)的事件,這里也就是頁面加載進(jìn)來調(diào)用第一匿名函數(shù)

          document.getElementById("btn"):獲取id為btn的元素,也就是將按鈕獲取過來;document.getElementById("btn").onclick:點(diǎn)擊按鈕時,觸發(fā)第二個匿名函數(shù)

          容導(dǎo)讀

          有兩種方式:1、函數(shù)聲明2、函數(shù)表達(dá)式 函數(shù)聲明會提升 ,函數(shù)表達(dá)式不會。閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見方式,是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。由于作用域鏈的機(jī)制導(dǎo)致一個問題,循環(huán)里的 匿名函數(shù)取得的任何變量都是最后一個值。閉包所保存的是整個變量對象,而不是某個特殊的變量。this對象 this對象是在運(yùn)行時基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局范圍就是window,如果在對象內(nèi)部就指向這個對象。而閉包卻在運(yùn)行時指向window,因?yàn)殚]包并不屬于這個對象的屬性或方法。

          函數(shù)表達(dá)式

          有兩種方式:1、函數(shù)聲明2、函數(shù)表達(dá)式
          函數(shù)聲明會提升,函數(shù)表達(dá)式不會。
          函數(shù)聲明,在執(zhí)行函數(shù)之前會先讀取函數(shù)聲明。

          sayhi()//‘hi’
          function sayhi(){
           console.log('hi');
          }
          //不會出錯

          函數(shù)表達(dá)式

          sayhi()//‘hi’
          var sayhi=function(){
           console.log('hi');
          }
          //會出錯

          函數(shù)表達(dá)式和函數(shù)聲明中沒有函數(shù)名的函數(shù),都是匿名函數(shù)

          //不要這樣做!,有的瀏覽器用第一個聲明,有的用第二個
          if(condition){
           function sayHi(){
           alert("Hi!");
           }
          } else {
           function sayHi(){
           alert("Yo!");
           }
          }
          //可以這樣做
          var sayHi;
           if(condition){
           sayHi = function(){
           alert("Hi!");
           };
          } else {
           sayHi = function(){
           alert("Yo!");
           };
          }

          閉包

          閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見方式,是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。

          • 閉包可以讓外側(cè)函數(shù)的局部變量駐留內(nèi)存,實(shí)現(xiàn)局部變量的累加,過度使用閉包導(dǎo)致性能下降,內(nèi)存泄漏

          function a(){
           var age=1;
           return function(){
           age++;
           return age;
           } 
          }
          var x=a();
          console.log(x())//2
          console.log(x())//3
          • 由于作用域鏈的機(jī)制導(dǎo)致一個問題,循環(huán)里的匿名函數(shù)取得的任何變量都是最后一個值。閉包所保存的是整個變量對象,而不是某個特殊的變量。

          function box() {
           var arr = [];
           for (var i = 0; i < 5; i++) {
           arr[i] = function() {
           return i;
           };
           }
           return arr;
          }
          var b = box(); //得到函數(shù)數(shù)組
          alert(b.length); //得到函數(shù)集合長度
          for (var i = 0; i < b.length; i++) {
           console.log(b[i]()); //輸出每個函數(shù)的值,都是最后一個值55555
          }

          因?yàn)閎中存的是匿名函數(shù)對象,當(dāng)bi執(zhí)行匿名函數(shù)時,box()中的for循環(huán)早已執(zhí)行完畢,i早已變成5.
          解決方法1:讓匿名函數(shù)自我執(zhí)行

          function box() {
           var arr = [];
           for (var i = 0; i < 5; i++) {
           arr[i] = (function(i) {
           return i;
           })(i);
           }
           return arr;
          }
          var b = box(); //得到函數(shù)數(shù)組
          alert(b.length); //得到函數(shù)集合長度
          for (var i = 0; i < b.length; i++) {
           console.log(b[i]); //輸出0,12,3,4
          }

          解決方法2:匿名函數(shù)下在創(chuàng)建一個匿名函數(shù),外側(cè)匿名函數(shù)自執(zhí)行

          function box() {
           var arr = [];
           for (var i = 0; i < 5; i++) {
           arr[i] = (function(num) {
           return function() {
           return num;//具體數(shù)字
           };
           })(i)
           }
           return arr;
          }
          var b = box(); //得到函數(shù)數(shù)組
          alert(b.length); //得到函數(shù)集合長度
          for (var i = 0; i < b.length; i++) {
           console.log(b[i]()); //輸出 01234
          }

          this對象

          this對象是在運(yùn)行時基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局范圍就是window,如果在對象內(nèi)部就指向這個對象。而閉包卻在運(yùn)行時指向window,因?yàn)殚]包并不屬于這個對象的屬性或方法。

          var user='window';
          var obj={
           user:'obj',
           getUserName:function(){
           return function(){
           return this.user;
           }
           }
          }
          console.log(obj.getUserName()());//window

          解決1:強(qiáng)制指向特定對象

          console.log(obj.getUserName().call(obj));//obj
          console.log(obj.getUserName().apply(obj));//obj

          解決2:復(fù)制this,得到上一個作用域的this對象

          var user='window';
          var obj={
           user:'obj',
           getUserName:function(){
           var that=this;
           return function(){
           return that.user;
           }
           }
          }
          console.log(obj.getUserName()());//obj

          匿名函數(shù)仿塊級作用域

          for循環(huán)中的var i在外部也能訪問

          function box(count) {
          for (var i=0; i<count; i++) {}
          var i; //就算重新聲明,也不會覆蓋前面的值,除非重新初始化
          alert(i);
          }
          box(2);//2

          解決1:
          //模仿塊級作用域(私有作用域)
          (function () {
          //這里是塊級作用域
          })();

          //使用塊級作用域(私有作用域)改寫
          function box(count) {
          (function () {
          for (var i = 0; i<count; i++) {}
          })();
          alert(i); //報錯,無法訪問
          
          }
          box(2);

          解決2:ES6中使用let

          function box(count) {
          for (let i=0; i<count; i++) {}
          alert(i); //i報錯
          
          }
          box(2);

          參考資料:JavaScript高級程序設(shè)計(第3版)

          數(shù)的編寫與使用

          在程序設(shè)計語言中函數(shù)是一段具有特殊功能的代碼,同時也是一組可以重復(fù)使用的代碼。通過函數(shù)這一對象的使用,進(jìn)一步提高了程序開發(fā)的模塊化與高度多的代碼復(fù)用性。各種程序設(shè)計語言都對函數(shù)的定義及使用有著嚴(yán)格的語法規(guī)則。本文主要介紹如何在JavaScript中定義函數(shù)、使用函數(shù),并對遞歸函數(shù)這一特殊類型函數(shù)進(jìn)行說明。


          JavaScript函數(shù)基本語法

          JavaScript中所定義的函數(shù)主要由函數(shù)定義關(guān)鍵字、函數(shù)名稱、函數(shù)參數(shù)、執(zhí)行代碼段與函數(shù)返回值5部分所組成。同時要求函數(shù)在使用過程中需要先定義函數(shù),再調(diào)用函數(shù)。JavaScript函數(shù)定義基本語法描述如下:

          JavaScript函數(shù)定義基本語法

          JavaScript函數(shù)定義基本語法描述如上圖,說明如下:

          函數(shù)定義語法說明


          函數(shù)調(diào)用與形參&實(shí)參

          函數(shù)定義完成之后,就可以通過調(diào)用該函數(shù)完成特定的功能。函數(shù)調(diào)用方式較為簡單,只需要給出函數(shù)名稱與所傳遞參數(shù),如果參數(shù)為空,只需要給出名稱后面的括號即可。關(guān)于參數(shù)部分需要注意形參與實(shí)參概念的區(qū)分。其中在函數(shù)定義中用于解釋說明語言的參數(shù)為形參。在函數(shù)調(diào)用過程中替代形參參與實(shí)際運(yùn)算的參數(shù)為實(shí)參。示例說明如下:

          形參與實(shí)參示例說明


          匿名函數(shù)

          匿名函數(shù)(Anonymous function),顧名思義是指沒有名字的函數(shù),即在上面給出的基本語法中functionName部分可以省略的函數(shù)。在JavaScript中提供兩類基本匿名函數(shù)定義方式,一種是將匿名函數(shù)封裝為表達(dá)式,一種是將匿名函數(shù)賦值給變量形式。兩類匿名函數(shù)基本語法描述如下:

          匿名函數(shù)的定義形式

          匿名函數(shù)定義形式描述如上圖所示,上文中計算解決值函數(shù)我們可以使用兩種方法改寫為匿名函數(shù),實(shí)現(xiàn)描述如下:

          匿名函數(shù)使用實(shí)例


          遞歸函數(shù)

          遞歸函數(shù)是一類特殊的函數(shù)類型,簡單理解即為在一個函數(shù)的內(nèi)部調(diào)用了該函數(shù)自身。在使用遞歸函數(shù)是需要注意產(chǎn)生遞歸的條件與遞歸終止的條件。如同循環(huán)控制語句一樣,沒有遞歸終止的條件,程序?qū)恢闭加觅Y源,無法結(jié)束釋放資源。遞歸函數(shù)的說明可以從階乘的計算這一案例展開說明。階乘計算過程描述如下:

          階乘計算原理

          階乘計算過程描述如上圖所示,我們可知階乘問題的解決主要在于遞推關(guān)系的挖掘與終止條件的確定。本例中遞推關(guān)系為N!=N*(N-1)!,終止條件為1!=1;在明確這兩點(diǎn)之后我們可以編寫遞歸函數(shù)實(shí)現(xiàn)問題求解。遞歸函數(shù)描述如下圖:

          階乘問題的遞歸求解編程實(shí)現(xiàn)


          經(jīng)典遞歸問題舉例

          爬樓梯問題是使用遞歸算法進(jìn)行問題求解的經(jīng)典案例之一,爬樓梯問題主要只是假設(shè)有N階樓梯,需要從最底層爬到最高層,在上樓過程中每步只允許上1層或者2層,計算爬到N層總共方法有多少種?

          爬樓梯方法問題

          爬樓梯方法問題采用遞歸思想還是比較簡單的,我們可以從小人最后一步考慮。小人上到最高層N層時只能有兩種方法:

          ①從N-2層跨越2層到達(dá)N層;

          ②從N-1層跨越1層到達(dá)N層;

          則計算到達(dá)N層的方法f(n)就等于到達(dá)N-1層方法f(n-1)與達(dá)N-2層方法f(n-2)之和。這就找到了我們進(jìn)行遞推的關(guān)系式,終止條件即為f(1)=1和f(2)=2;

          因此我們可以編程實(shí)現(xiàn)計算,實(shí)現(xiàn)代碼如下:

          爬樓梯遞歸求解代碼


          本頭條號長期關(guān)注編程資訊分享;編程課程、素材、代碼分享及編程培訓(xùn)。如果您對以上方面有興趣或代碼錯誤、建議與意見,可以聯(lián)系作者,共同探討。更多程序設(shè)計相關(guān)教程及實(shí)例分享,期待大家關(guān)注與閱讀!JavaScript基礎(chǔ)教程系列教程鏈接如下:

          JavaScript基礎(chǔ)教程(六)流程控制之循環(huán)語句

          JavaScript基礎(chǔ)教程(五)流程控制之條件語句


          主站蜘蛛池模板: 国产一区二区在线视频| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 亚洲天堂一区二区三区四区| 日韩精品一区二区三区老鸦窝| 无码人妻精品一区二区三区久久| 日本强伦姧人妻一区二区| 国产精品99精品一区二区三区| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 亚洲色精品三区二区一区| 日韩免费观看一区| 国产午夜精品一区二区| 狠狠爱无码一区二区三区| 日本一区免费电影| 中文字幕日韩欧美一区二区三区| 人妻无码一区二区三区AV| 免费视频一区二区| 久久se精品一区二区影院| 冲田杏梨高清无一区二区| 国产在线观看精品一区二区三区91| 国产香蕉一区二区在线网站| 精品视频无码一区二区三区| 性色AV一区二区三区| 久久精品午夜一区二区福利 | 性色av闺蜜一区二区三区| 亚洲AV一区二区三区四区| 九九无码人妻一区二区三区| 亚洲视频免费一区| 日韩av片无码一区二区不卡电影 | 久久久久久人妻一区二区三区| 51视频国产精品一区二区| 亚洲av无码一区二区三区在线播放| 国产精品亚洲午夜一区二区三区| 无码人妻精品一区二区| 日韩人妻一区二区三区蜜桃视频| 色窝窝无码一区二区三区色欲| 麻豆AV一区二区三区久久| 亚洲中文字幕在线无码一区二区 | 久久人妻无码一区二区| 日韩一区二区精品观看| 中文人妻av高清一区二区| 亚洲国产福利精品一区二区|