閉包_定時器_BOM

下面的代碼輸出多少?修改代碼讓fnArri 輸出 i。使用兩種以上的方法

var fnArr = [];
for (var i = 0; i < 10; i ++) {
    fnArr[i] =  function(){
        return i;
    };
}
console.log( fnArr[3]() );  //10,執行的時候i是全局變量10,所以整個數組元素執行后都會是10

如果想要讓fnArr[i]執行后輸出i,需要用函數構建一個新的局部作用域

  • 第一種方法
var fnArr = [];
for (var i = 0; i < 10; i ++) {
  var temp = function (i) {     //這里的i是新聲明的形參,最終是由函數執行時傳入的實參決定
    console.log(i);             //這里的i是傳入的參數  執行后輸出0,1,2,3,4,5,6,7,8,9
  }
  temp(i);                      //i通過傳參進入temp
  fnArr[i] =  function(){
      return i;
  };
}
console.log( fnArr[3]() ); //3

整理后得到

var fnArr = [];
for (var i = 0; i < 10; i ++) {
  !function (i) {    
    fnArr[i] =  function(){
        return i;
    };        
  }(i);                      
}
console.log( fnArr[3]() ); //3
  • 第二種方法
var fnArr = [];
for (var i = 0; i < 10; i ++) {
  var temp = function () {      //構建局部作用域
    return function (){
      return i;
    }
  }
  fn = temp(i);        //循環的過程中把i傳入temp存值
  fnArr[i] = fn;      
}
console.log( fnArr[3]() ); //3

整理后得到

var fnArr = [];
for (var i = 0; i < 10; i ++) {
  fnArr[i] = function(i){
    return function () {
       return i;
    }
  }(i);
}
console.log( fnArr[3]() );
  • 第三種方法
var fnArr = [];
for (let i = 0; i < 10; i ++) {//使用var申明的變量在代碼塊外面能被識別,但是let命令卻不能被識別,這樣就實現了js的塊級作用域,我們在使用條件語句 循環語句等就會不擔心變量污染的問題了
    fnArr[i] =  function(){
        return i;
    };
}
console.log( fnArr[3]() );  //10,執行的時候i是全局變量10,所以整個數組元素執行后都會是10

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

var Car = (function(){
   var speed = 0;//speed = 30;speed = 40;speed = 30;speed = 20;
   function setSpeed(s){
       speed = s;
   }
   function getSpeed(){
     return speed;
   }
   function accelerate(){
      speed += 10;//speed = speed + 10
   }
   function decelerate(){
      speed > 0?speed -= 10 : speed; //30
   }
   function getStatus(){
     return speed > 0?'running':'stop';
   }
   return {
      'setSpeed': setSpeed,
      'getSpeed': getSpeed,
      'accelerate': accelerate,
      'decelerate': decelerate,
      'getStatus': getStatus
      'speed':'error'

   };
})();
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

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

var a = 1;
setTimeout(function(){
    a = 2;
    console.log(a);    //2   作用域鏈 定時器被放入執行隊列的最后
}, 0);
var a ;
console.log(a);        //1   作用域鏈
a = 3;
console.log(a);        //3   作用域鏈

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

var flag = true;
setTimeout(function(){       //定時器被放入執行隊列的最后
    flag = false;
},0)
while(flag){}                //setTimeout會等待它執行完畢才會執行,此時flag永遠是true,進入死循環。
console.log(flag);

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

for(var i=0;i<5;i++){
    setTimeout(function(){
         console.log('delayer:' + i );       ////代碼會依次輸出 0 1 2 3 4 ,delayer: 5 輸出5次
    }, 0);
    console.log(i);
}
  • 使用閉包
for(var i=0;i<5;i++){
  setTimeout(function(i){
    return function(){
         console.log('delayer:' + i );
    }
  }(i), 0);
  console.log(i);
}

獲取元素的真實寬高

function trueStyle(element,pseduoElement){
     //IE不支持window.getComputedStyle(),支持element.currentStyle();
    return element.currentStyle ? element.currentStyle : window.getComputedStyle(element,pseduoElement);
}
let trueWidth = trueStyle(element).width;
let trueHeight = trueStyle(element).height;

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

  • URL的編碼/解碼方法

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

  1. decodeURI()
  2. decodeURIComponent()
  3. encodeURI()
  4. encodeURIComponent()
  • 區別

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

  1. ASCII字母
  2. 數字
  3. ~!@#$&*()=:/,;?+'

encodeURIComponent方法不會對下列字符編碼

  1. ASCII字母
  2. 數字
  3. ~!*()'

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

實際例子來說,encodeURIComponent會把 http:// 編碼成 http%3A%2F%2F 而encodeURI卻不會。

如果你需要編碼整個URL,然后需要使用這個URL,那么用encodeURI。 encodeURI("http://www.cnblogs.com/season-huang/some other thing"); //"http://www.cnblogs.com/season-huang/some%20other%20thing";

其中,空格被編碼成了%20。但是如果你用了encodeURIComponent,那么結果變為

"http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2Fsome%20other%20thing"
當你需要編碼URL中的參數的時候,那么encodeURIComponent是最好方法。


var param = "http://www.cnblogs.com/season-huang/"; //param為參數
param = encodeURIComponent(param);
var url = "http://www.cnblogs.com?next=" + param;
console.log(url) //"http://www.cnblogs.com?next=http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2F"

參數中的 "/" 可以編碼,如果用encodeURI肯定要出問題,因為后面的/是需要編碼的

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

function isAndroid() {
    return /Android/.test(window.navigator.userAgent);
}

function isiPhone() {
    return /iphone/i.test(window.navigator.userAgent);
}

function isiPad() {
    return /ipad/i.test(window.navigator.userAgent);
}

function isIOS() {
    return /(ipad)|(iphone)/.test(widow.navigator.userAgent);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 var fnArr...
    saintkl閱讀 377評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 題目2: 封裝一個...
    Taaaaaaaurus閱讀 354評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]() 輸出 i。使用 兩種以上的方法 題目2: 封裝一個...
    peaceChierdo閱讀 248評論 0 0
  • 題目1: 下面的代碼輸出多少?修改代碼讓 fnArri 輸出 i。使用 兩種以上的方法 題目2: 封裝一個汽車對象...
    無目的閱讀 189評論 0 0
  • BOM課件閉包概念1閉包概念2 1.下面的代碼輸出多少?修改代碼讓fnArr[i]() 輸出 i。使用兩種以上的方...
    饑人谷_米彌輪閱讀 152評論 0 0