javascript面试题目三

11.函数节流和防抖
(1).函数节流

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        html{
            height: 500%;
        }
    </style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
    //面试题:什么是函数节流?什么是函数防抖
    /*
        函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。
        - 有个需要频繁触发的函数,出于优化性能的角度,在规定时间内,只让函数触发的第一次生效,后面不生效。
    */
    /*
     *节流函数
     * fn 要被节流的函数
     * delay 规定的时间
    */
    function throlle(fn,delay){
        //记录上一次触发时间
        var lastTime=0;
        return function(){
            //记录当前触发时间
            var nowTime=Date.now();
        
            if(nowTime-lastTime>delay){
                //修正this指向问题
                fn.call(this);
                // 同步函数
                lastTime=nowTime;
            }
        }
    }
    document.onscroll=throlle(function(){console.log('onscroll事件被触发'+Date.now());},2000);
</script>
</body>
</html>

  

(2). 防抖函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        html{
            height: 500%;
        }
    </style>
</head>
<body>
<button id="btn">按钮</button>
<script type="text/javascript">
   
    /*
        防抖函数:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效
    */
    /*
     *防抖函数
     * fn 要被防抖的函数
     * delay 规定的时间
    */
    function debounce(fn,delay){
        //记录上一次触发时间
        var timer=null;
        return function(){

            //清除上一次的延迟
            clearTimeout(timer);

            //重新设置延时器
            timer=setTimeout(function(){
                //修正this指向问题
                fn.apply(this);
            },delay);
        }
    }
    document.getElementById('btn').onclick=debounce(function(){console.log('点击事件被触发了'+Date.now());},1000);
</script>
</body>
</html>

  

12.跨域问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
    // 面试题:什么是跨域?解决跨域的办法有哪些?
    /*
      1.同源策略
       - 浏览器安全策略
       - 协议名、域名、端口号必须完全一致
       
      2.跨域
       -违背同源策略就会产生跨域
       
      3.解决跨域
       jsonp、cors、服务代理...
       (前端)     (后端)

    */
    //创建script标签
    var script=document.createElement('script');

    //设置回调函数
    function getDate(data){
        console.log(data);
    }

    //设置script 的src属性,设置请求地址

    script.src='http://localhost:3000?callback=getDate';
    
    //让script生效
    document.body.appendChild(script);
</script>
</body>
</html>

  

13.node.js事件轮询机制

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
  /* 
    面试题:nodejs的事件轮询机制
  */

  
   setTimeout(function(){
    console.log('setTimeout()');
   },0);
   setImmediate(function(){
    console.log('setImmediate()');
   });
   process.nextTick(function(){
    console.log('process.nextTick()')
   })
   /*
       process.nextTick()
       setTimeout()
       setImmediate()

        nodejs的事件轮询机制:借助libuv库实现的
        包括事件轮询机制,分为6个阶段
          1.timers 定时器阶段
            计时和执行到点的定时器回调函数
          2.pending callbacks
            某些操作系统(例如TCP错误类型)的回调函数
          3.idle,prepare
            准备工作
          4.poll轮询阶段
            如果轮询队列不为空,依次同步取出轮询队列中的第一个回调函数执行,直到轮询队列为空或者达到系统最大的限制
            如果轮询队列为空
              如果之前设置过setImmediate函数的
                直接进入下一个check阶段
              如果之前没有设置过setImmediate函数
                在当前poll阶段等待
                  直到轮询队列添加回调函数,就去第一阶段执行
                  如果定时器到点了,也进入到下一个阶段
          5.check查询阶段
            执行setImmediate设置的回调函数
          6.close callbacks 关闭阶段
            执行close事件回调函数
    
          process.nextTick能在任意阶段优先执行
   */

</script>
</body>
</html>

  

14.从一个url地址到网页的最终渲染完成,发生了什么?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    /*
      面试题:从一个url地址到最终页面渲染完成,发生了什么?
    */

   /*
      1.DNS解析:将域名地址解析为IP地址
        - 浏览器DNS缓存
        - 系统DNS缓存
        - 路由器DNS缓存
        - 网络运营商DNS缓存
        - 递归搜索:blog.baidu.com
          -.com域名下查找DNS解析
          -.baidu域名下查找DNS解析
          -blog域名下查找DNS解析
          -出错了
      2.TCP连接:TCP三次握手
        - 第一次握手,由浏览器发起,告诉服务器我要发送请求了
        - 第二次握手,由服务器发起,告诉浏览器,我准备接收了,你赶紧发送吧。
        - 第三次握手,由浏览器发送,告诉服务器,我马上就发了,你准备接收吧
      3.发送请求
        - 请求报文:HTTP协议的通信内容
      4.接受相应
        - 响应报文
      5.渲染页面
        - 遇见HTML标记,浏览器调用HTML解析器解析成Token并构建成dom树
        - 遇见style/link标记,浏览器调用css解析器,处理css标记并构建cssom树
        - 遇到script标记,调用JavaScript解析器,处理script代码(绑定事件,修改dom树/cssom树)
        - 根据渲染树来计算布局,计算每个节点的几何信息(布局)
        - 将各个节点颜色绘制到屏幕上(渲染)

      注意:这个五个步骤不一定按照顺序执行,如果dom树或cssom树被修改,可能会执行多次布局和渲染,往往实际页面中,这些步骤会多次执行。

      6. 断开连接:TCP四次挥手
      第一次挥手,由浏览器发起的,发送给服务器,我东西发送完了,(请求报文)你准备关闭吧。
      第二次挥手,由服务器发起的,告诉浏览器,我东西接收完了(请求报文),我准备关闭了,你也准备关闭吧。
      第三次挥手,由服务器发起的,告诉浏览器,我东西发送完了(响应报文),你准备关闭吧。
      第四次挥手,由浏览器发起的,告诉服务器,我东西接收完了(响应报文),我准备关闭了,你也准备关闭吧。
   */

</script>
</body>
</html>

  

15.什么是闭包?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
  /*
    理解:什么是闭包?
      1.密闭的容器, 类似于set,map容器
      2.闭包是一个对象,存放数据的格式:key:value
    形成的条件:
      1.函数嵌套
      2.内部函数引用外部函数的局部变量
    闭包的优点:
      延长外部函数局部变量的生命周期
    闭包的缺点:
      容易造成内存泄露
    注意点:
      1.合理的使用闭包
      2.用完闭包要及时清除(销毁)
  */
  // 简单的闭包
  function fun(){
    let a=1;
    function b(){
      console.log(a);
    }
    b();
  }
  fun();
  // Global 全局的变量对象
  // Local 函数里面局部的变量对象

  //闭包的应用场景
  function fun(){
    let count=1;
    return function(){
      count++;
      console.log(count);
    }
  }
  var fun2=fun();
  fun2();   //2
  fun2();   //3

  /* 
    说说它们的输出情况
  */
  function fun(n,o){
    console.log(o)
    return {
      fun:function(m){
        return fun(m,n)
      }
    }
  }
  var a=fun(0)
  a.fun(1)
  a.fun(2)
  a.fun(3) //underfined,0,0,0
 
  var b=fun(0).fun(1).fun(2).fun(3)// underfined,0,1,2
  var c=fun(0).fun(1)
  c.fun(2)
  c.fun(3)// underfined,1,1
</script>
</body>
</html>

  

16.变量提升 && 执行上下文

/*
    变量升级 预处理
  */
  /*
    js引擎在代码正式执行之前会做一个预处理的工作:
      1.收集变量
      2.收集函数
      依据:
        var 将var后边的变量定义但不赋值 var username=undefined;
        function(){}
  */
  console.log(username); //答案:underfined
  var username='kobe';
  console.log(username) //kobe

  fun();            //答案:正常执行函数
  function fun(){
    console.log('fun()');
  }
  /*
    作用域:作用域是在代码定义的时候产生的
    //执行上下文 执行上下文对象(this)

    执行上下文(excute context) EC
    理解:代码执行的环境
    时机(产生时):代码正式执行之前会进入到执行环境
    工作:
      1.创建变量对象:
        1)变量
        2)函数及函数的参数
        3)全局:window
        4)局部:抽象的但是确实存在
      2.确认this的指向
        1)全局:this --->window
        2)局部:this --->调用其的对象
      3.创建作用域链
        父级作用域链+当前的变量对象
      4.扩展
      ECobj={
        变量对象:{变量,函数,函数的形参}
        scopeChain(作用域链):父级作用域链+当前的变量对象
        this:{window || 调用其的对象}
      }
  */

  

猜你喜欢

转载自www.cnblogs.com/Lolita-web/p/10415176.html
今日推荐