美文网首页
闭包_定时器_BOM

闭包_定时器_BOM

作者: 尾巴尾巴尾巴 | 来源:发表于2017-07-31 15:11 被阅读0次

    下面的代码输出多少?修改代码让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

          本文链接:https://www.haomeiwen.com/subject/lroncxtx.html