1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      javascript中的作用域和閉包-創(chuàng)新互聯(lián)

      這篇文章運(yùn)用簡單易懂的例子給大家介紹javascript中的作用域和閉包,代碼非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

      成都創(chuàng)新互聯(lián)長期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為東平企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì),東平網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

      作用域

      JS中有兩種作用域:全局作用域|局部作用域

      栗子1

      console.log(name);      //undefined
      var name = '波妞';
      var like = '宗介'
      console.log(name);      //波妞
      function fun(){
          console.log(name);  //波妞
          console.log(eat)    //ReferenceError: eat is not defined
          (function(){
              console.log(like)   //宗介
              var eat = '肉'
          })()
      }
      fun();

      1. name定義在全局,在全局可以訪問到,所以 (2) 打印能夠正確打印;

      2. 在函數(shù)fun中,如果沒有定義name屬性,那么會(huì)到它的父作用域去找,所以 (3) 也能正確打印。

      3. 內(nèi)部環(huán)境可以通過作用域鏈訪問所有外部環(huán)境,但外部環(huán)境不能訪問內(nèi)部環(huán)境的任何變量和函數(shù)。類似單向透明,這就是作用域鏈,所以 (4) 不行而 (5) 可以。

      那么問題來了,為什么第一個(gè)打印是"undefined",而不是"ReferenceError: name is not defined"。原理簡單的說就是JS的變量提升

      變量提升:JS在解析代碼時(shí),會(huì)將所有的聲明提前到所在作用域的最前面


      栗子2

      console.log(name);      //undefined
      var name = '波妞';
      console.log(name);      //波妞
      function fun(){
          console.log(name)   //undefined
          console.log(like)   //undefined
          var name = '大西瓜';
          var like = '宗介'
      }
      fun();

      相當(dāng)于

      var name;
      console.log(name);      //undefined
      name = '波妞';
      console.log(name);      //波妞
      function fun(){
          var name;
          var like;
          console.log(name)   //undefined
          console.log(like)   //undefined
          name = '大西瓜';
          like = '宗介'
          console.log(name)   //大西瓜
          console.log(like)   //宗介
      }
      fun();

      注意:是提前到當(dāng)前作用域的最前面


      栗子3

      printName();     //printName is not a function
      var printName = function(){
          console.log('波妞')
      }
      printName();       //波妞

      相當(dāng)于

      var printName;
      printName();     //printName is not a function
      printName = function(){
          console.log('波妞')
      }
      printName();       //波妞

      這樣一來就好理解了,函數(shù)表達(dá)式在聲明的時(shí)候還只是個(gè)變量


      栗子4

      {
          var name = '波妞';
      }
      console.log(name)   //波妞
      
      (function(){
          var name = '波妞';
      })()
      console.log(name)   //ReferenceError: name is not defined
      
      {
          let name = '波妞';
      }
      console.log(name)   //ReferenceError: name is not defined

      從上面的栗子可以看出,不可以草率的認(rèn)為JS中var聲明的變量的作用范圍就是大括號(hào)的起止范圍,ES5并沒有塊級(jí)作用域,實(shí)質(zhì)是函數(shù)作用域;ES6中有了let、const定義后,才有了塊級(jí)作用域。


      栗子5

      function p1() { 
          console.log(1);
      }
      function p2() { 
          console.log(2);
      }
      (function () { 
          if (false) {
              function p1() {
                  console.log(3);
              }
          }else{
              function p2(){
                  console.log(4)
              }
          }
          p2();
          p1()
      })();       
      //4
      //TypeError: print is not a function

      這是一個(gè)非常經(jīng)典的栗子,聲明提前了,但是因?yàn)榕袛鄺l件為否,所以沒有執(zhí)行函數(shù)體。所以會(huì)出現(xiàn)"TypeError: print is not a function"。while,switch,for同理

      閉包

      函數(shù)與對其狀態(tài)即詞法環(huán)境(lexical environment)的引用共同構(gòu)成閉包(closure)。也就是說,閉包可以讓你從內(nèi)部函數(shù)訪問外部函數(shù)作用域。在JavaScript中,函數(shù)在每次創(chuàng)建時(shí)生成閉包。

      上面的定義來自MDN,簡單講,閉包就是指有權(quán)訪問另一個(gè)函數(shù)作用域中變量的函數(shù)。


      ● 閉包的關(guān)鍵在于:外部函數(shù)調(diào)用之后其變量對象本應(yīng)該被銷毀,但閉包的存在使我們?nèi)匀豢梢栽L問外部函數(shù)的變量對象.,

      //舉個(gè)例子
      function makeFunc() {
          var name = "波妞";
          function displayName() {
              console.log(name);
          }
          return displayName;
      }
      
      var myFunc = makeFunc();
      myFunc();

      JavaScript中的函數(shù)會(huì)形成閉包。 閉包是由函數(shù)以及創(chuàng)建該函數(shù)的詞法環(huán)境組合而成。這個(gè)環(huán)境包含了這個(gè)閉包創(chuàng)建時(shí)所能訪問的所有局部變量

      在例子中,myFunc 是執(zhí)行 makeFunc 時(shí)創(chuàng)建的 displayName 函數(shù)實(shí)例的引用,而 displayName 實(shí)例仍可訪問其詞法作用域中的變量,即可以訪問到 name 。由此,當(dāng) myFunc 被調(diào)用時(shí),name 仍可被訪問,其值 '波妞' 就被傳遞到console.log中。創(chuàng)建閉包最常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)


      ● 通常,函數(shù)的作用域及其所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷毀。但是,在創(chuàng)建了一個(gè)閉包以后,這個(gè)函數(shù)的作用域就會(huì)一直保存到閉包不存在為止

      //例二
      function makeAdder(x) {
        return function(y) {
          return x + y;
        };
      }
      
      var add5 = makeAdder(5);
      var add10 = makeAdder(10);
      
      console.log(add5(2));  // 7
      console.log(add10(2)); // 12
      
      //釋放對閉包的引用
      add5 = null;
      add10 = null;

      從本質(zhì)上講,makeAdder 是一個(gè)函數(shù)工廠 — 他創(chuàng)建了將指定的值和它的參數(shù)相加求和的函數(shù)。在上面的示例中,我們使用函數(shù)工廠創(chuàng)建了兩個(gè)新函數(shù) — 一個(gè)將其參數(shù)和 5 求和,另一個(gè)和 10 求和。

      add5 和 add10 都是閉包。它們共享相同的函數(shù)定義,但是保存了不同的詞法環(huán)境。在 add5 的環(huán)境中,x 為 5。而在 add10 中,x 則為 10。

      閉包的作用域鏈包含著它自己的作用域,以及包含它的函數(shù)的作用域和全局作用域。


      ● 閉包只能取得包含函數(shù)中的任何變量的最后一個(gè)值

      //栗子1
      function arrFun1(){
          var arr = [];
          for(var i = 0 ; i < 10 ; i++){
              arr[i] = function(){
                  return i
              }
          }
          return arr
      }
      console.log(arrFun1()[9]());     //10
      console.log(arrFun1()[1]());     //10
      
      //栗子2
      function arrFun2(){
          var arr = [];
          for(var i = 0 ; i < 10 ; i++){
              arr[i] = function(num){
                  return function(){
                      return num
                  };
              }(i)
          }
          return arr
      }
      console.log(arrFun2()[9]());     //9
      console.log(arrFun2()[1]());     //1

      栗子 1 中,arr數(shù)組中包含10個(gè)匿名函數(shù),每個(gè)函數(shù)都可以訪問外部的變量 i , arrFun1 執(zhí)行后,其作用域被銷毀,但它的變量依然存在內(nèi)存中,能被循環(huán)中的匿名函數(shù)訪問,這是的 i 為 10;

      栗子 2 中,arr數(shù)組中有是個(gè)匿名函數(shù),其匿名函數(shù)內(nèi)還有匿名函數(shù),最內(nèi)層匿名函數(shù)訪問的 num 被 上一級(jí)匿名函數(shù)保存在了內(nèi)存中,所以可以訪問到每次的 i 的值。

      關(guān)于javascript中的作用域和閉包就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


      網(wǎng)頁標(biāo)題:javascript中的作用域和閉包-創(chuàng)新互聯(lián)
      本文地址:http://www.ef60e0e.cn/article/dcdpcd.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        南开区| 高清| 陆河县| 平陆县| 锦州市| 康乐县| 龙游县| 邵阳县| 阳西县| 韶关市| 门源| 象州县| 新乡市| 晋城| 德令哈市| 肇源县| 广汉市| 东乡县| 南郑县| 舞钢市| 房山区| 苍山县| 玛纳斯县| 城口县| 阳江市| 安龙县| 和硕县| 阿勒泰市| 阿克苏市| 如皋市| 宣化县| 吐鲁番市| 武穴市| 沙河市| 霍城县| 阜阳市| 淳安县| 平度市| 昭觉县| 平阴县| 申扎县|