闭包-定时器-BOM

作者: 南山码农 | 来源:发表于2017-08-08 15:09 被阅读0次

    题目1: 下面的代码输出多少?修改代码让 fnArri 输出 i。使用 两种以上的方法

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

    方法一:

    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 ++) {
        fnArr[i] =  (function(i){ //IIFE & 闭包
            return function(){
                return i;
            }
        })(i);
    }
    console.log( fnArr[3]() );  //3
    

    方法三:

    var fnArr = [];
    for (let i = 0; i < 10; i ++) { //使用ES6: let
        fnArr[i] =  function(){
            return 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(){
         if(speed>10){ 
            speed-=10;
          }else {
             speed = 0;  
        }
      }
    
      function getStatus(){
          if(speed>0){
          console.log( "running");
          }else{
          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,那是因为setTimeout函数的运行机制是,将制定的代码移出本次执行,等到下一轮EventLoop时,再检查时间,执行代码。这意味着,先console.log(1),再console.log(3),本次代码执行完后再检查时间,执行console.log(2)

    题目4:下面这段代码输出结果是? 为什么?

    var flag = true;
    setTimeout(function(){
        flag = false;
    },0)
    while(flag){}
    console.log(flag);
    

    浏览器会陷入while死循环。因为setTimeout函数的运行机制是,将制定的代码移出本次执行,等到下一轮EventLoop时,再检查时间,执行代码。所以,while循环将一直循环下去,本次EventLoop无法结束,无法进入setTimeout。

    题目5: 下面这段代码输出?如何输出delayer: 0, delayer:1...(使用闭包来实现)

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

    修改后:

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

    题目6: 如何获取元素的真实宽高

    function getCss(curEle,attr){
          return window.getComputedStyle ? window.getComputedStyle(curEle,null)[attr] : curEle.currentStyle[attr];
    }
    getCss(ele,'width')//宽度
    getCss(ele,'height')//高度
    

    题目7: URL 如何编码解码?为什么要编码?

    编码原因:

    • Url参数字符串中使用key=value键值对这样的形式来传参,键值对之间以&符号分隔,如/s?q=abc&ie=utf-8。如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。
    • Url的编码格式采用的是ASCII码,而不是Unicode,这也就是说你不能在Url中包含任何非ASCII字符,例如中文。否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。

    ps:URI是统一资源标识的意思,通常我们所说的URL只是URI的一种。典型URL的格式如下所示。下面提到的URL编码,实际上应该指的是URI编码。

    Paste_Image.png

    Url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。

    解决办法:

    三个编码的函数——escape,encodeURI,encodeURIComponent——都是用于将不安全不合法的Url字符转换为合法的Url字符表示,它们有以下几个不同点。
      安全字符不同:
      下面列出了这三个函数的安全字符(即函数不会对这些字符进行编码)

    • escape(69个):*/@+-._0-9a-zA-Z
    • encodeURI(82个):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
    • encodeURIComponent(71个):!'()*-._~0-9a-zA-Z

    兼容性不同:escape函数是从Javascript 1.0的时候就存在了,其他两个函数是在Javascript 1.5才引入的。但是由于Javascript 1.5已经非常普及了,所以实际上使用encodeURI和encodeURIComponent并不会有什么兼容性问题。

    对Unicode字符的编码方式不同:这三个函数对于ASCII字符的编码方式相同,均是使用百分号+两位十六进制字符来表示。但是对于Unicode字符,escape的编码方式是%uxxxx,其中的xxxx是用来表示unicode字符的4位十六进制字符。这种方式已经被W3C废弃了。但是在ECMA-262标准中仍然保留着escape的这种编码语法。encodeURI和encodeURIComponent则使用UTF-8对非ASCII字符进行编码,然后再进行百分号编码。这是RFC推荐的。因此建议尽可能的使用这两个函数替代escape进行编码。

    适用场合不同:encodeURI被用作对一个完整的URI进行编码,而encodeURIComponent被用作对URI的一个组件进行编码。从上面提到的安全字符范围表格来看,我们会发现,encodeURIComponent编码的字符范围要比encodeURI的大。我们上面提到过,保留字符一般是用来分隔URI组件(一个URI可以被切割成多个组件,参考预备知识一节)或者子组件(如URI中查询参数的分隔符),如:号用于分隔scheme和主机,?号用于分隔主机和路径。由于encodeURI操纵的对象是一个完整的的URI,这些字符在URI中本来就有特殊用途,因此这些保留字符不会被encodeURI编码,否则意义就变了。

    题目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 /iphone|ipad/i.test(navigator.userAgent);
    }

    相关文章

      网友评论

        本文标题:闭包-定时器-BOM

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