3.作用域和閉包

//------------------題目------------------------->
1.說一下對變量提升的理解

針對兩個場景一個script、一個是構(gòu)造函數(shù)中俄删,它的變量的聲明和定義
以及函數(shù)的聲明都會被提前,放在前面过咬,所以會導(dǎo)致我們有變量提升主觀上的理解壳猜。(執(zhí)行上下文的知識)

    *1虹曙、變量定義
    *2谷誓、函數(shù)聲明(注意和函數(shù)表達式的區(qū)別)

2.說明this集中不同使用場景

     *1绒障、作為構(gòu)造函數(shù)執(zhí)行
     *2、作為對象屬性執(zhí)行
     *3捍歪、作為普通函數(shù)執(zhí)行
     *4户辱、call apply bind

3.創(chuàng)建10個<a>標簽,點擊時候彈出來對應(yīng)的序號

     var i ;
     for(i=0;i<10;i++){
         //自執(zhí)行函數(shù)糙臼,就是不用調(diào)用庐镐,只要定義完成,立即執(zhí)行的函數(shù)
         (function(i){
            //  函數(shù)作用域
              var a = document.createElement('a');
             a.innerHTML = i+'<br>';
             a.addEventListener('click',function(e){
                 e.preventDefault();
                 alert(i);//自由變量变逃,要去父級作用域獲取值
             });
             
             document.body.appendChild(a);
             
         })(i);
     }
   
   //閉包或者作用域使用的問題
4.如何理解作用域
    *自由變量
    *作用域鏈必逆,即自由變量的查找
    *閉包的兩個場景
5.實際開發(fā)中閉包的應(yīng)用
   //閉包是作用域知識點的實際應(yīng)用
   //閉包實際應(yīng)用中主要用于封裝變量,收斂權(quán)限\
   // 判斷用戶是不是第一次加載  
   function isFirstLoad(){
       
       //把存儲數(shù)據(jù)的數(shù)據(jù)源存起來,其他外邊拿不到   
       var _list = [];//變量前面有下劃線名眉,說明這個是私有變量
       return function(id){
           if(_list.indexOf(id) >=0){
               return false;
           }else{
               //_list這里是自由變量粟矿,要去它定義的父作用域去找
               _list.push(id);
               return true;
           }
       }
   }
   
    //使用
    var firstLoad = isFirstLoad();
    firstLoad(10); //true
    firstLoad(10); //false
    firstLoad(20); //true
    firstLoad(20); // false
   
   
    //在isFirstLoad函數(shù)外邊,根本不可能修改掉_list的值

//*******************知識點*******************************
一璧针、執(zhí)行上下文

執(zhí)行上下文.png
執(zhí)行機制.png

范圍:一段<script>或者一個函數(shù)
全局:變量定義、函數(shù)聲明
【一段<script>會生成一個全局的執(zhí)行上下文渊啰,執(zhí)行之前先去
把變量定義探橱、函數(shù)聲明拿出來】
函數(shù):變量定義、函數(shù)聲明绘证、this隧膏、arguments
**【針對一個函數(shù),會出現(xiàn)一個函數(shù)執(zhí)行上下文嚷那,函數(shù)執(zhí)行之前

          先把函數(shù)中的變量定義胞枕、函數(shù)聲明、this魏宽、arguments(函數(shù)
          中所有參數(shù)的集合)拿出來】**
          
    PS:注意‘函數(shù)聲明’和‘函數(shù)表達式’的區(qū)別:
    
     【函數(shù)聲明】:
        //如果這里執(zhí)行fn();不會報錯;
        /*這段程序執(zhí)行之前會把聲明的
        函數(shù)提到前面去腐泻,先聲明出來,執(zhí)行不會報錯*/
        
         function fn(name){
           age = 20;
           console.log(name,age);
           var age;
          }
      【函數(shù)表達式】:
      (本質(zhì)上執(zhí)行的只是這個變量队询,并不是把函數(shù)聲明提前了)
        //在這里執(zhí)行fn1();會報錯派桩;
        /*所有var fn1,在執(zhí)行之前不是個函數(shù)蚌斩,在執(zhí)行之前會把var fn1
        提到前面去,并且賦值成undefined,var fn1并沒有去執(zhí)行*/
          var fn1 =function(){};
           
           
  /*在執(zhí)行第一行之前铆惑,會把所有的變量的聲明和函數(shù)聲明都拿出來*/
   // 寫程序先定義會執(zhí)行(增加代碼可讀性))
  eg. 1.
  /*
  全局函數(shù)作用域(會把變量的聲明,和函數(shù)的聲明挪到前面去送膳,
  先聲明了员魏;函數(shù)的聲明是把函數(shù)挪前面去了,變量的聲明把變量挪
  前面去了叠聋,并且賦值undefined撕阎,占位)
  
  */
   console.log(a);//undefined
   var a = 100;
   
   eg.2.
   fn('zhangsan');//'zhangsan' 20
   function fn(name){
       
       /*都會把變量提前,都會把函數(shù)提前*/
       /*在函數(shù)執(zhí)行之前碌补,this闻书、arguments已經(jīng)確定了值*/
       console.log(this);//window
       
       /*["zhangsan",callee:function,
       symbol{symbol.iteareator}:function]*/
       console.log(arguments);
       
       age = 20;
       console.log(name,age);
       var age;
   }

二、this

1.this要在執(zhí)行時才能確認值脑慧,定義時無法確認

      1.作為構(gòu)造函數(shù)執(zhí)行
      
      function Foo(name){
          //this = {};
         this.name = name; 
         //return this;
      }
      var f = new Foo("zhangsan"); 
      
     2.作為對象屬性執(zhí)行
     
     var obj = {
         name:"A",
         printName:function(){
            console.log(this.name);
         }
     };
     
     obj.printName();
     
      3.作為普通函數(shù)執(zhí)行(this應(yīng)該是window)
      
      function fn(){
          console.log(this);// this === window
      }
      fn();
      
      4.call apply bind
     /**call apply **/
      function  fn1(name,age){
          alert(name);
          console.log(this);//this就是第一個參數(shù)
      };
      
      /*執(zhí)行fn1這個函數(shù)魄眉,用{X:100}當this,"zhangsan"
      當?shù)谝粋€參數(shù)*/
      fn1.call({X:100},"zhangsan",20);
      
      //會把后面的參數(shù)當數(shù)組來傳遞
      fn1.apply({X:100},['zhangsan',20]);
      
      /**bind**/
     var fn2 = function (name,age){
          alert(name);
          console.log(this);
      }.bind({Y:200});
      
      //沒bind之前this是window闷袒;bind之后this是{Y:100}
      fn2('zhangsan',20);
      
      
      
      eg:
      var a ={
         name:'A',
         fn:function(){
             console.log(this.name);
         }
         
      };
      
      a.fn(); //this === a
      
      a.fn.call({name:'B'}); //this === { name :'B'}
      
      var fn1 = a.fn;
      // this === window; this.name是undefined或者其他值
      fn1(); 

三坑律、作用域

1.JS沒有塊級作用域
2.只有函數(shù)和全局作用域

    //------ 無塊級作用域--------------
    if(true){
        var name = 'zhangsan';
    }
    console.log(name); //zhangsan
    // 和把name在外邊定義然后再if中賦值是一樣的
    // 推薦寫法:在外邊定義然后再下面賦值
    var name;
    if(true){
      name = 'zhangsan';   
    }
    console.log(name);
    
    //---------- 函數(shù)和全局作用域--------------
    
    //這個a是全局的,誰都可以獲取,誰都可以改(不安全)
    var a =100;
    
    function fn(){
        /*函數(shù)中定義晃择,和外邊是隔絕的冀值,外邊是改不了的;
          從外邊得不到宫屠,也改不了列疗,只能從函數(shù)里去用;
          防止自己的變量被污染浪蹂,把所有變量都定義在一個大的函數(shù)里
        */
        var a =200;
        console.log('fn',a);//在函數(shù)范圍內(nèi)獲取
    }
    
     console.log('global',a);
     
     fn(); // global: 100; fn :200

四抵栈、作用域鏈

(一個自由變量一直不斷的往父級作用域去找,形成一個鏈式結(jié)構(gòu))
-- 哪個作用域定義了這個函數(shù)坤次,這個函數(shù)父級作用域就是誰古劲,和函數(shù)執(zhí)行沒有關(guān)系

       //作用域完整的使用形式、場景
        1.eg:
        var a =100;
        function fn(){
           var b =200;
          
        //當前作用域沒有定義的變量缰猴,即“自由變量”
        /*函數(shù)體內(nèi)沒規(guī)定a是誰产艾,但是打印a,就要向父級作用域
        找a滑绒,父級作用域是全局作用域闷堡,所以a就找到var a =100;
        函數(shù)父級作用域是什么疑故,是函數(shù)定義的時候的父級作用域
        缚窿,不是函數(shù)執(zhí)行時候的作用域*/
           console.log(a);
           console.log(b);
      }
      
      fn();
      
      2.eg:
      var a =100;
      function F1(){
          var b =200;
          function F2(){
              var c = 300;
              console.log(a); //100 a是自由變量
              console.log(b); //200 b是自用變量
              console.log(c); //300
          }
          F2();
      }
      F1();

五、閉包(作用域鏈的具體應(yīng)用)

閉包的使用場景:
1.函數(shù)作為返回值
2.函數(shù)作為參數(shù)傳遞(把函數(shù)傳遞到另一個函數(shù)中執(zhí)行)

   eg:1.函數(shù)作為返回值 
   //F1 這個函數(shù)最終返回的是一個函數(shù)
   function F1(){
       
       /*F1作用域里面的a*/
       var a =100;
       
       /*
        返回一個函數(shù)焰扳;
       */
       return function(){
           /*
           a是自由變量倦零,自由變量去父級作用域(F1)找;
           一個函數(shù)的父級作用域吨悍,是它定義時候的作用域扫茅,
           而不是執(zhí)行時候的作用域
           */
           console.log(a);
       }
   }
   
   //把F1()賦值給f1,f1就是一個函數(shù)了
   var f1 = F1();
   
   /*是全局作用域里面的a*/
   var a =200;
   
    f1(); //100
    
    
    eg:2.函數(shù)作為參數(shù)傳遞
    
    function F1(){
        var a =100;
        
        //F1返回一個函數(shù)
        return function(){
            console.log(a);
        }
    }
    
    //把F1()賦值給f1育瓜,f1就是一個函數(shù)了
    var f1 = F1();
    
    function F2(fn){
        var a =200;
        
        fn();
    }
   
   F2(f1);//100
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葫隙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子躏仇,更是在濱河造成了極大的恐慌恋脚,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焰手,死亡現(xiàn)場離奇詭異糟描,居然都是意外死亡,警方通過查閱死者的電腦和手機书妻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門船响,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事见间×拇常” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵米诉,是天一觀的道長菱蔬。 經(jīng)常有香客問我,道長史侣,這世上最難降的妖魔是什么拴泌? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮抵窒,結(jié)果婚禮上弛针,老公的妹妹穿的比我還像新娘叠骑。我一直安慰自己李皇,他們只是感情好,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布宙枷。 她就那樣靜靜地躺著掉房,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慰丛。 梳的紋絲不亂的頭發(fā)上卓囚,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音诅病,去河邊找鬼哪亿。 笑死,一個胖子當著我的面吹牛贤笆,可吹牛的內(nèi)容都是我干的蝇棉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼芥永,長吁一口氣:“原來是場噩夢啊……” “哼篡殷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起埋涧,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤板辽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后棘催,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劲弦,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年醇坝,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓶您。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呀袱,靈堂內(nèi)的尸體忽然破棺而出贸毕,到底是詐尸還是另有隱情,我是刑警寧澤夜赵,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布明棍,位于F島的核電站,受9級特大地震影響寇僧,放射性物質(zhì)發(fā)生泄漏摊腋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一嘁傀、第九天 我趴在偏房一處隱蔽的房頂上張望兴蒸。 院中可真熱鬧,春花似錦细办、人聲如沸橙凳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岛啸。三九已至,卻和暖如春茴肥,著一層夾襖步出監(jiān)牢的瞬間坚踩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工瓤狐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瞬铸,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓础锐,卻偏偏與公主長得像嗓节,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子郁稍,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容