閉包、定時器、BOM

BOM課件
閉包概念1
閉包概念2

1.下面的代碼輸出多少?修改代碼讓fnArr[i]() 輸出 i。使用兩種以上的方法

      var fnArr = [];
      
      // 1.
      for(var i = 0; i < 10; i++){
        (function(n){
          fnArr[i] = function(){
            return n;
          }
        })(i);
      }

      // 2.
      for(var i = 0; i < 10; i++){
        fnArr[i] = (function(n){
          return function(){
            return n;
          }
        })(i);
      }
      console.log(fnArr[3]());

2.封裝一個汽車對象,可以通過如下方式獲取汽車狀態

      var Car = (function(){
         var speed = 0;
         function setSpeed(s){
          speed = s
         }
         function getSpeed(){
          console.log(speed);
         }
         function accelerate(){
          speed += 10;
         }
         function decelerate(){
          speed -= 10;
         }
         function getStatus(){
          if(speed > 0) {
            console.log('running');
          }else{
            speed = 'error';
            console.log('stop');
          }
         }

         return {
            setSpeed: setSpeed,
            getSpeed: getSpeed,
            accelerate: accelerate,
            decelerate: decelerate,
            getStatus: getStatus,
         }
      })()


      Car.setSpeed(30);
      Car.getSpeed(); //30
      Car.accelerate();
      Car.getSpeed(); //40;
      Car.decelerate();
      Car.decelerate();
      Car.getSpeed(); //20
      Car.getStatus(); // 'running';
      Car.decelerate(); 
      Car.decelerate();
      Car.getStatus();  //'stop';
      Car.speed;  //error

3.下面這段代碼輸出結果是? 為什么?

  var a = 1;
  setTimeout(function(){
      a = 2;
      console.log(a);
  }, 0);
  var a ;
  console.log(a);
  a = 3;
  console.log(a);
  • 結果是1,3,2
    • 經過變量提升,第一個輸出的為1,第二個輸出為3
    • setTimeout(code|function,millisec)會放在執行代碼隊列的最后面,最后輸出為2

4.下面這段代碼輸出結果是? 為什么?

  var flag = true;
  setTimeout(function(){
      flag = false;
  },0)
  while(flag){}
  console.log(flag);
  • 結果是一直不停循環直到瀏覽器崩潰
    • while(flag=true) {}會一直運行,而setTimeout(code|function,millisec)會放在執行代碼隊列的最后面,所以flag一直都是true

5.下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來實現)

      for(var i=0;i<5;i++){
          setTimeout(function(n){
            return function(){
              console.log('delayer:' + n );
            }
          }(i), 0);
          console.log(i);
        }

6.如何獲取元素的真實寬高

 <head>
    <meta charset="utf-8">
    <style type="text/css">
      .box {
        width: 200px;
        height: 200px;
        background-color: pink;
        margin: 100px auto;
      }
    </style>
</head>
  <body>
    <div class="box"></div>
    <script type="text/javascript">
        var box = document.querySelector('.box');
        console.log(getComputedStyle(box,null)['margin']);
    </script>
  </body>

7.URL 如何編碼解碼?為什么要編碼?

  • JavaScript提供四個URL的編碼/解碼方法。

    • decodeURI() //解碼
    • decodeURIComponent() //解碼
    • encodeURI() //編碼
    • encodeURIComponent() //編碼
  • 區別

  • encodeURI方法不會對下列字符編碼

    • ASCII字母
    • 數字
    • ~!@#$&*()=:/,;?+'
  • encodeURIComponent方法不會對下列字符編碼

    • ASCII字母
    • 數字
    • ~!*()'

所以encodeURIComponent比encodeURI編碼的范圍更大。

  • 當我們需要編碼一個URL并且要使用的時候,使用encodeURI來編碼。當需要編碼URL中的參數時,用encodeURIComponent,因為后面的/是需要編碼的。

    <button class="btn">點我</button>
    <script type="text/javascript">
      var btn = document.querySelector('.btn');
      btn.addEventListener('click',function(){
        var param = "http://www.cnblogs.com/season-huang/";
        param = encodeURI(param);
        var url = "http://www.cnblogs.com?next=" + param;
        console.log(url);
        window.open(url)
      })
    </script>
    

8.補全如下函數,判斷用戶的瀏覽器類型

  function isAndroid(){
     return /android/i.test(navigator.userAgent);
    }
    function isIphone(){
      return /iphone/i.test(navigator.userAgent);
    }
    function isIpad(){
      return /ipad/i.test(navigator.userAgent);
    }
    function isIOS(){
      return /(ipad)|(iphone)/i.test(navigator.userAgent);
    }
  • 閉包概念
    • 官方對閉包的解釋是:一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。

    • 閉包的特點:

      • 1.作為一個函數變量的一個引用,當函數返回時,其處于激活狀態。
      • 2.一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。
        • 簡單的說,javascript允許使用內部函數---即函數定義和函數表達式位于另一個函數的函數體內。而且,這些內部函數可以訪問它們所在的外部函數中聲明的所有局部變量、參數和聲明的其他內部函數。當其中一個這樣的內部函數在包含它們的外部函數之外被調用時,就會形成閉包。
    function closure(){
      var str = "I'm a part variable.";
      return function(){
        alert(str);
      }
    }
    var fObj = closure();
    fObj();
  • 在上面代碼中,str是定義在函數closure中局部變量,若str在closure函數調用完成以后不能再被訪問,則在函數執行完成后str將被釋放。但是由于函數closure返回了一個內部函數,且這個返回的函數引用了str變量,導致了str可能會在closure函數執行完成以后還會被引用,所以str所占用的資源不會被回收。這樣closure就形成了一個閉包。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 方法1:聲明個函數,創...
    曉風殘月1994閱讀 388評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArri 輸出 i。使用 兩種以上的方法 方法一: 方法二: 方法三...
    南山碼農閱讀 292評論 0 1
  • 1.題目1: 下面的代碼輸出多少?修改代碼讓 fnArri 輸出 i。使用 兩種以上的方法 方法一: 立即執行函數...
    饑人谷_啦啦啦閱讀 409評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 var fnArr...
    saintkl閱讀 378評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 題目2: 封裝一個...
    Taaaaaaaurus閱讀 354評論 0 0