闭包_定时器_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);
}

你可能感兴趣的:(闭包_定时器_BOM)