前端面试题

前端面试题汇总 HTML——CSS——JS——es6——Vue——微信小程序 HTML面试题 1.请至少写出5个HTML块级元素标签。 div,p,form,table,h1~h6 2.请至少写出5个行内元素标签。 span,img,input,button,a 3.写出空元素。 br,hr,link 4.写出table标签下包含哪些标签元素。 tr,th,td,tfoot,tbody 5.很... 阅读详情

理论系列 

  1. script 引入方式

    1. html 静态 <script> 引入
    2. js 动态插入 <script>
    3. <script defer> : 异步加载,和元素解析一起进行,但是等元素解析完成后才执行。如果有多个defer脚本,则按照它们在文档中出现的顺序依次执行。
    4. <script async> : 异步加载,和元素解析一起进行,在当前js解析完成后立即执行,可能执行时会阻塞元素渲染。如果有多个async脚本,则它们的执行顺序是不确定的。
  2. webpack和gulp的区别

    1. gulp 致力于自动化和优化你的工作流,侧重于整体过程的控制管理。通过定义许多task来执行构建任务,使用起来更像是任务流。因此他的任务定义和管理是webpack所没有的。
      1. 特点:
        1. 任务定义和管理
        2. 基于文件 stream 的构建
    2. webpack 有人也称之为 模块打包机 ,由此也可以看出webpack更侧重于模块打包。
      我们可以把开发中的所有资源(js文件、css文件、图片、字体等)都可以看成模块。
      最初webpack本身就是为前端JS代码打包而设计的,后来被扩展到其他资源的打包处理。webpack是通过 loader(加载器) 和 plugins(插件) 对资源进行处理的。
      1. 特点:
        1. 按照模块的依赖来构建文件
        2. 通过loader来支持不同模块
  3.  使用javascript创建一个函数test1。此函数接受一个参数seconds,调用此函数可实现等待指定秒数。请注意,请使用setInterval

    function test1(seconds) {
      let timer = null;
      return new Promise(resolve => {
        timer = setInterval(() => {
          console.log('123');
          resolve(clearInterval(timer));
        }, seconds)
      })
    }
  4. 请使用setTimeout实现一个函数test2。 此函数接受三个参数: callback, seconds, n。 该函数被调用后,会每隔设定的秒数调用callback函数n次

    function test2(callback, seconds, n) {
      let executor = (callback, seconds) => {
        setTimeout(() => {
          for (let index = 0; index < n.length; index++) {
            callback();
          }
          executor(callback, seconds);
        }, time)
      }
      executor(callback, seconds);
    }
  5.  有一个用元祖记录着多个点坐标的二维数组,例如[[30,30],[20,30],[30,9],[10,10]],请用js将这四个点按从左往右,从上到下排序,输出[[10,10],[20,30],[30,9],[30,30]]

    // 使用sort方法对点进行排序  
    points.sort(function(a, b) {  
        // 首先按第一个元素(x坐标)排序  
        if (a[0] < b[0]) {  
            return -1;  
        }  
        if (a[0] > b[0]) {  
            return 1;  
        }  
        // 如果第一个元素相同,则按第二个元素(y坐标)排序  
        if (a[1] < b[1]) {  
            return -1;  
        }  
        if (a[1] > b[1]) {  
            return 1;  
        }  
        // 如果两个元素都相同,则返回0  
        return 0;  
    });  
      
  6. 请编写一个函数test3。 该函数接受一个参数data。 data为一个仅包含字符串的数组。 这个数组中每个元素都不可以包含“, ”。如果有“, ”,需要将对应的元素分割。 例如,

    // 运行test3(["id1,", "id2,id3", "id4"]) 后, 输入数组变为["id1", "id2", "id3", "id4"]
    // 运行test3(["id1,", "id2,id3", "id4,id5,id6"]) 后, 输入数组变为["id1", "id2", "id3", "id4", "id5", "id6"]
    
    function test3(data) {
      // 创建新数据
      // return data = data.toString().split(",").filter(e => !!e);
      // 修改原始数据
      data.forEach((element,index) => {
        let reg = /\w+/g
        let matchs = element.match(reg);
        console.log('matchs :>> ', matchs);
        if (matchs) {
          if (matchs.length == 1) data.splice(index, 1, matchs[0])
          else matchs.map((e,i) => {
            if (1 == 0) data.splice(index, 1, e)
            else data.splice(index+i, 0, e)
          })
        }
      });
    }
  7. 数组与树形数据互相转化

    //列表到树的转化
    function arrayToTree(items) {  
      const result = [];  
      const lookup = {};  
      // 遍历数组,将每个项目的id作为key存入lookup对象中  
      for (let item of items) {
        // 如果当前项目未存在于lookup对象中,则创建一个新数组  
        if (!lookup[item.id]) {  
          lookup[item.id] = {  
            children: [],  
            // 将当前项目放入lookup对象中对应的数组中  
            ...item 
          };  
        }
      }
      for (let item of items) {  
        // 如果当前项目的parentId存在于lookup对象中,则将当前项目添加到其children数组中  
        if (lookup[item.parentId]) {  
          lookup[item.parentId].children.push(lookup[item.id]);  
        } else {  
          // 当前项没有父节点 -> 顶层  
          result.push(lookup[item.id]);  
        }  
      }  
      return result;  
    }
    function arrayToTree(data) {
      const res = [];
      data.forEach((item) => {
        const parent = data.find((node) => node.id === item.parentId);
        if (parent) {
          parent.children = parent.children || [];
          parent.children.push(item);
        } else {
          // * 根节点
          res.push(item);
        }
      });
      return res;
    }
    
    //树转换成为列表
    function treeToArray(tree) {
      let arr = [];
      function traverse(node) {
        arr.push(node);
        if (node.children && node.children.length > 0) {
          node.children.forEach(traverse);
        }
      }
      traverse(tree);
      return arr;
    }
    function treeToList(tree) {
        const { children } = this.config;
        const result = [...tree];
        for (let i = 0; i < result.length; i++) {
          if (!result[i][children]) {continue;}
          result.splice(i + 1, 0, ...result[i][children]);
        }
        return result;
     }
    
  8. DOM 元素e的 e.getAttribute(propName)和 e.propName 有什么区别和联系

    1. e.getAttribute:获取的是标签上属性,可以通过e.setAttribute(propName, propValue)设置标签上属性

    2. e.propName:获取的是元素对象上属性

  9. 设置小于浏览器最小字体的实现

    {
      font-size: 20px;
      transform: scale(0.5); //缩放
    }
  10. 正则中使用变量

    let name = 'John Doe';
    let regex = /Hello, ${name}!/;
    console.log(regex.test('Hello, John Doe!'));  // 输出: true
  11. H5自定义属性data-*?

      const root = document.getElementById("root");
      console.log(root.dataset); // DOMStringMap {weather: "阳光明媚"}
      root.dataset.rain = '大暴雨'; // 添加属性
      console.log(root.dataset); // DOMStringMap {weather: "阳光明媚", rain: "大暴雨"}
      delete root.dataset.rain; // 删除操作
      console.log(root.dataset); // DOMStringMap {weather: "阳光明媚"}
      console.log(root); // <div id="root" data-weather="阳光明媚"> 多云转晴 </div>
      root.dataset.cloudy = '大雨转阴'; // 添加属性
    
      // 循环获取所有属性及属性值
      let dataset = {};
      for (let i = 0; i < root.attributes.length; i++) {
          let name = root.attributes[i].name;
          if (name.substring(0, 5) == 'data-') {
             dataset[name.substring(5)] = root.attributes[i].value;
          };
      };
      console.log(root.dataset, dataset); // DOMStringMap {weather: "阳光明媚", cloudy:             
                                   "大雨转阴"} {weather: "阳光明媚", cloudy: "大雨转阴"}
    
    
      console.log(root.getAttribute('data-cloudy')); // 大雨转阴
      root.setAttribute('data-cloudy', '阴转小雨');
      console.log(root.dataset); // DOMStringMap {cloudy: "阴转小雨",weather: "阳光明媚"}
    
    
  12. attribute 和 property 的区别是什么?

    1. attribute 是 dom 元素在文档中作为 html 标签拥有的属性

    2. property 就是 dom 元素在 js 中作为对象拥有的属性

    3. 对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的,但是对于自定义的属性来说,他们是不同步的

  13. http状态码

    switch (error.response.status) {
       case 301: error.message = '永久移动(301)'//今后任何新的请求都应使用新的URI代替
     break;
       case 302: error.message = '临时移动(302)'//资源只是临时被移动。客户端继续使用原有URI
     break;
       case 303: error.message = '请求错误(303)'//表示必须临时重定向,查看其它地址。与301类似。使用GET和POST请求查看
     break;
       case 304: error.message = '未修改(304)'//所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,这样可以减少网络开销
     break;
       case 400: error.message = '请求错误(400)'//请求方式错误,比如get使用了post
     break;
       case 401: error.message = '未授权,请重新登录(401)';//验证码错误/账号密码错误/没有携带Token
     break;
       case 403: error.message = '拒绝访问(403)';//表示没有权限,服务器拒绝访问请求
     break;
       case 404: error.message = `请求地址错误: ${error.response.config.url}`;
     break;
       case 405: error.message = '请求方法未允许(405)';
     break;
       case 408: error.message = '请求超时(408)';
     break;
       case 500: error.message = '服务端内部错误(500)';
     break;
       case 501: error.message = '服务未实现(501)';
     break;
       case 502: error.message = '网络错误(502)';//作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应。一般是架构网关层问题
     break;
       case 503: error.message = '服务不可用(503)';//表示服务器繁忙,或者服务器负载,通常这只是一个临时状态
     break;
       case 504: error.message = '网络超时(504)';
     break;
       case 505: error.message = 'HTTP版本不受支持(505)';
     break;
       default: error.message = `连接错误: ${error.message}`;
    }
  14. new关键字

    new 是一个关键字,用于创建对象和构造函数。在内存中创建一个新的空对象,让this指向创建出来的空对象,执行构造函数里面的代码,给这个空的对象添加属性和方法,返回这个新对象(所以构造函数里面不需要return)
    function myNew(constructor, ...args) {
      const obj = Object.create(constructor.prototype);
    
      const result = constructor.apply(obj, args);
    
      if (typeof result === 'object' && result !== null) {
        return result;
      } else {
        return obj;
      }
    }
  15. HTML标签a和link的区别

    <a>标签是用来创建超链接的,也叫锚标签;
    <link>标签则是用来链接外部资源的。
    <link rel="stylesheet" href="styles.css" type="text/css"media="screen">
    href:指定外部资源的URL。
    rel:指定当前文档与目标文档之间的关系(例如stylesheet表示引入CSS文件,icon表示图标文件)。
    type:指定外部资源的MIME类型(例如text/css)。
    media:指定外部资源适用的媒体类型(例如screen、print)。
  16. 什么是标识符?

    1. 在JS中,可以自定义命名的东西都是属性标识符
    2. 比如变量名,函数名,参数名都是标识符
  17. 数组扁平化

    var arr = [1, [2, [3, 4, 5]]];
    function flatten(arr) {
        return arr.flat(infinit)
    }
    function flatten(arr) {
        arr = arr.toString().split(',');
        var newArr = arr.map((item) => {
            item = +item
            return item
        })
        return newArr
    }
    function flatten(arr) {
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr);
        }
        return arr;
    }
    function flatten(arr) {
        return arr.reduce(function(prev, next){
            return prev.concat(Array.isArray(next) ? flatten(next) : next)
        }, [])
    }
  18. 函数接受一个字符串参数,返回该字符串中出现次数最多的字符。

    maxBlock(str) {
      if (!str) return;
      let map = {};
      for (var i = 0; i < str.length; i++) {
        if (map[str[i]]) {
         map[str[i]] += 1;
        } else {
         map[str[i]] = 1;
        }
      }
      return Object.values(map).sort((a, b) => b - a)[0];
    },
  19. 数组排序

    //选择排序
    //基本思想:首先在未排序数组中找到最小(大)元素,存放在数组的起始位置。
             //再从剩余数组元素中继续寻找最小(大)元素,返回放在已排序数组的末尾
             //重复第二步,直到所有元素都排序完成
    var arr = [123,203,23,13,34,65,65,45,89,13,1];
    for(var i=0;i<arr.length;i++){
    	for(var j=i+1;j<arr.length;j++){
    		//如果第一个比第二个大,就交换他们两个位置
    		if(arr[i]>arr[j]){
    			var temp = arr[i];
    			arr[i] = arr[j];
    			arr[j] = temp;
    		}
    	}
    }
    
    //冒泡排序
    //基本思想:一次比较两个相邻的数,如果不符合规则互换位置
    //一次比较就能够将最大或最小的值放在数组最后一位
    for(var i=0; i<arr.length-1; i++){
    	//每一轮比较要比多少次
    	for(var j=0; j<arr.length-1-i; j++){
    	    //如果第一个比第二个大,就交换他们两个位置
    	    if(arr[j]>arr[j+1]){
    	        var temp = arr[j];
    	        arr[j] = arr[j+1];
    	        arr[j+1] = temp;
    	    }
    	}    
    }
    
    //快速排序(依托递归函数)
    //基本思想:在已知数据集合中随便去一个基准(pivot)
             //将其余数据以基准为中心,大于分放右边,小于的放左边
             //将左右两个子集重复以上两个步骤
    function quickSort(tempArr){
    	//递归终止条件
    	if(tempArr.length<=1){
    		return tempArr;
    	};
    	//取基准 一般取第一个或者最后一个
    	var pivotIndex = Math.floor(tempArr.length/2);
    	var pivot = tempArr.splice(pivotIndex,1);
    	//分左右
    	var leftArr = [];
    	var rightArr = [];
    	for(var i=0;i<tempArr.length;i++){
    		if(tempArr[i]>pivot){
    			rightArr.push(tempArr[i]);
    		}else{
    			leftArr.push(tempArr[i]);
    	    };
    	};
    	return quickSort(leftArr).concat(pivot,quickSort(rightArr));
    };
  20. 防抖:任务频繁触发的情况下,重新计时,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

    function debounce(fn) {
        // 1、创建一个标记用来存放定时器的返回值
        let timeout = null;
        return function() {
          // 2、每次当用户点击/输入的时候,把前一个定时器清除
          clearTimeout(timeout);
          // 3、然后创建一个新的 setTimeout,
          // 这样就能保证点击按钮后的 interval 间隔内
          // 如果用户还点击了的话,就不会执行 fn 函数
          timeout = setTimeout(() => {
            fn.call(this, arguments);
          }, 1000);
      };
    }
  21. 节流:指定时间间隔内只会执行一次任务

    function throttle(fn) {
      // 1、通过闭包保存一个标记
      let canRun = true;
      return function() {
        // 2、在函数开头判断标志是否为 true,不为 true 则中断函数
        if(!canRun) return;
        // 6、将 canRun 设置为 false,防止执行之前再被执行
        canRun = false;
        // 3、定时器
        setTimeout(() => {
          fn.call(this, arguments);
          // 4、执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
          canRun = true;
        }, 1000);
    };
  22. 对象深拷

    浅拷贝:只是拷贝一层,更深层次对象级别的只拷贝了地址
    深拷贝:层层拷贝,每一级别的数据都会拷贝
    这篇文章有详细的说明:javaScript实现浅拷贝和深拷贝的方法有哪些?看这一篇就够了(详细)_js深拷贝和浅拷贝方法-优快云博客
    1. function deepCopy(newObj,obj) {
        for(var key in obj) {
          //判断属性值属于哪种数据类型
          //属性值 obj[key]
          //1.判断这个值是否为数组(数组也属于特殊对象,也是引用类型数据)
          if(obj[key] instanceof Array) {
            newObj[key] = []
            deepCopy(newObj[key],obj[key]) //运用递归,把原对象属性值给新对象
            //判断这个值是否为对象
          } else if(obj[key] instanceof Object) {
            newObj[key] = {}
            deepCopy(newObj[key],obj[key]) //运用递归,把原对象属性值给新对象
          } else {
            //若是普通数据类型
            newObj[key] = obj[key]
          }	
        }
      }
      
      // 数组和对象和基本数据类型的深拷贝,但不能处理函数、RegExp、Date
      JSON.parse(JSON.stringify())
  23. css中伪元素和伪类的差别

    伪类是针对 HTML 元素的状态描述,可以描述 HTML 元素的不同阶段或状态,例如:link、:visited、:hover 等,:first-child 和 :last-child 表示伪类。
    伪元素是用于描述 HTML 元素的一部分,它们实际上是虚拟的 DOM 节点,而不是真实的 HTML 元素,例如::before 和 ::after。
  24. XSS和CSRF的区别

    XSS 是把受害者 的 Cookie 偷盗过来,而 CSRF 则是借用了受害者的 Cookie。
  25. export和export default导出的内容可以更改么

    export导出的内容:需要包再{}中接收,导出的对象属性在外部脚本中是可以修改的。
    export default导出的内容:在一个模块中只能有一个,不需要加{},导出的值在外部脚本中不可修改,只是属性可以被修改。
  26. ajax和fetch的区别

    1. ajax基于原生的XHR开发架构不清晰,fetch采用了Promise的异步处理机制,使用比ajax简单
    2. ajax利用XMLHttpRequest对象来请求数据,fetch只是全局变量window的一个方法。
    3. fetch只对网络错误报错,对400,500都当做成功的请求,需要封装去处理
    4. fetch没有办法原生监测请求的进度,而XHR可以(onprogress)
  27. 完整的HTTP事务是怎样的一个过程

    1、域名解析:使用DNS协议进行域名解析
    2、建立连接:发起TCP三次握手
    3、发起http请求:建立TCP连接成功后,浏览器发起http请求
    4、响应http请求:服务端响应http请求,浏览器得到返回response
    5、解析response:浏览器解析response,并请求其它的资源(如js、css等)
    6、浏览器渲染展示页面:浏览器根据内核对页面进行渲染展示
    7、断开连接:TCP四次挥手
    详细说明:【精选】一次完整的http请求过程_一个完整的http请求过程详细_三也_小也的博客-优快云博客

  28. TCP、UDP的区别

    所有的TCP、UDP都是以IP数据报格式传输。
    1. TCP协议:传输控制协议
      1. 面向连接,需要先建立连接,结束后再断开连接,常见的三次握手、四次挥手,即用于此协议
      2. 传输速度慢
      3. 数据要求按顺序传输,传输过程中数据报不需要携带目的地址,保证数据的正确性
      4. 基于流模式传输,可传输大数据
      5. 系统资源要求多
      6. 主要提供完整性服务
    2. UDP协议:用户数据报协议
      1. 面向非连接

      2. 传输速度快

      3. 对传输顺序无要求,准确性无法保证,有丢包可能

      4. 基于数据报模式,按包传输,传输数据量少,一次传输的数据大小有限,最大64k

      5. 资源要求少

      6. 主要提供及时性服务

  29. vue属性的访问顺序

    vue2 inject => props => methods => data => computed => watch => provide

    vue3 porps => inject => methods => data => computed => watch => provide

  30. 什么是强缓存、协商缓存

    为了减少资源请求次数,加快资源访问速度,浏览器会对资源文件如图片、css文件、js文件等进行缓存,而浏览器缓存策略又分为强缓存和协商缓存。在强缓存里,是否使用缓存是由浏览器来确定的,而协商缓存则是由服务器来告诉浏览器是否使用缓存资源,也就是浏览器每一次都要发送请求到服务器询问是否使用缓存。
     

    强缓存就是浏览器本地根据服务器设置的过期时间来判断是否使用缓存,未过期则从本地缓存里拿资源,已过期则重新请求服务器获取最新资源。

    协商缓存则是浏览器本地每次都向服务器发起请求,由服务器来告诉浏览器是从缓存里拿资源还是返回最新资源给浏览器使用。

    强缓存的具体流程为:
    浏览器第一次请求远程服务器的某个资源时,如果服务器希望浏览器得到该资源后一段时间内不要再发送请求过来,直接从浏览器里的缓存里取,则服务器可以通过在响应头里设置Cache-Control、Expires。Expires是Http1.0规范,Cache-Control是Http1.1规范,Expires参照的是本地客户端的时间,而客户端的时间是可以被修改的,所以有了后来Http1.1规范的Cache-control,Cache-control的优先级要高于Expires。浏览器缓存资源的地方有两个:磁盘缓存(disk cache)和内存缓存(memory cache)。

    协商缓存的具体流程:
    浏览器初次请求资源,服务器返回资源,同时生成一个Etag值(哈希值)携带在响应头里返回给浏览器,当浏览器再次请求资源时会在请求头里携带If-None-Match,值是之前服务器返回的Etag的值,服务器收到之后拿该值与资源文件最新的Etag值做对比。如果没有变化则返回304,告诉浏览器继续使用缓存(不返回资源文件)。如果发生变化,则返回200和最新的资源文件给浏览器使用。除了Etag外,还有一个Last-Modified的属性,它是Http1.0规范的,服务器返回Last-Modified,浏览器请求头对应携带的是If-Modified-since,与Etag不同的是,Last-Modified的值是一个时间值,代表文件的修改时间,服务器通过对比文件的修改时间是否发生改变来判断是否使用缓存。相比Last-Modified,Etag优先级更高,使用上也更精确一些,因为有时候会存在文件内容并没有改变,但文件的修改时间变更了。

  31. 什么是跨域?说出几种解决跨域的办法?

    指浏览器不能执行其他网站的脚本(域名、协议、端口任意不相同),它是由浏览器的同源策略造成的,浏览器对js实施的安全限制。
    1. Jsonp 跨域 只能够实现get请求
    2. PostMessage
    3. 服务端设置Access-Control-Allow-Origin,若要带cookie请求:前后端都需要设置
    4. nginx反向代理接口跨域,做跳板机,反向代理访问domain2接口
    5. WebSocket实现了浏览器与服务器全双工通信,同时允许跨域通讯
  32. get和post的区别

    1.GET请求会被缓存,而POST请求不会被缓存
    2.GET请求会被保留在浏览器历史中,而POST请求则不会
    3.GET的安全性相对于POST较差,因为发送的数据是URL的一部分,而POST不会放到浏览器历史中
    4.GET向URL中传递数据,对数据长度有限制,POST则没有限制
  33. 垃圾回收机制

    自动内存管理技术,它的目的是为了有效地管理和回收那些不再使用的内存资源。
    1. 引用计数:统计对象的引用数量,当对象的引用数量变为零时,则认为该对象不再被使用,然后回收它的内存。(IE)
    2. 标记清除:将每个对象标记为活跃的或未使用的,然后删除未使用的对象。(chrome)
  34. 前台兼容性问题有哪些

    主要是常用浏览的(前端)API差异(HTML/CSS/Javascript 语法不兼容),渲染差异,浏览器内置样式不一致,字体渲染差异
  35. SEO优化

    模板引擎会影响SEO优化,为了解决这个问题,需要关注SEO的页面最好采用服务端渲染的方式(ssr)。
    设置正确的元标记和标题。使用 vue-meta 插件来管理和设置元标记和标题。
    压缩 CSS 和 JavaScript 文件、减少 HTTP 请求次数等方式来提高网页速度。
    创建 XML 站点地图。站点地图是一份清单,列出站点上所有页面的 URL。使用 vue-router-sitemap 插件生成 XML 站点地图。
  36. 浏览器一次可以从一个域名下请求多少资源

    1. 浏览器的并发请求数目限制是针对同一域名的,同一时间针对同一域名下的请求有一定数量限制,不同浏览器这个限制的数目不一样,超过限制数目的请求会被阻塞;
      目前的话,所有浏览器的并发数目一般限制在10以内。
  37. offsetWidth/offsetHeight,clientWidth/clientHeight,scrollWidth/scrollHeight 的区别?

    1. offsetWidth/offsetHeight 返回值包含 content + padding + border + 包含滚动条,效果与 e.getBoundingClientRect()相同
    2. clientWidth/clientHeight 返回值只包含 content + padding,如果有滚动条,也不包含滚动条
    3. scrollWidth/scrollHeight 返回值包含 content + padding + 溢出内容的尺寸
  38. 浏览器事件循环机制和Node事件循环机制的区别

    浏览器事件循环机制中,微任务的任务队列是在每个宏任务执行完之后执行。

    Node事件循环机制中,微任务会在事件循环的各个阶段之间执行,也就是说,一个阶段执行完毕,就会去执行微任务队列的任务。

  39. html5有哪些新特性

    1.拖拽释放(Draganddrop)API ondrop 自定义属性 data-id 获取 li.getAttribute(‘data-id’)或者 li.dataset.type=‘guoji’

    2.语义化更好的内容标签(header,nav,footer,aside,article,section)

    3.音频、视频 API(audio,video) 如果浏览器不支持自动播放怎么办?

    4.画布(Canvas)API 热 canvas 和 image 的区别?

    5.地理(Geolocation)API

    6.本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;sessionStorage 的数据在浏览器关闭后自动删除

    7.表单控件,calendar、date、time、email、url、search 、tel、file、number

    9.新的技术 webworker,websocket,Geolocation

  40. CSS3新特性

    1.过渡 transition: CSS属性,花费时间,效果曲线(默认ease),延迟时间(默认0)复制代码

    2.动画 animation:动画名称,一个周期花费时间,运动曲线(默认ease),动画延迟(默认0),播放次数(默认1),是否反向播放动画(默认normal),是否暂停动画(默认running)复制代码

    3.形状转换 transform:适用于2D或3D转换的元素

    rotate(30deg); translate(30px,30px); scale(.8); skew(10deg,10deg); rotateX(180deg); rotateY(180deg); rotate3d(10,10,10,90deg);

    4.选择器

    5.阴影 box-shadow: 水平阴影的位置 垂直阴影的位置 模糊距离 阴影的大小 阴影的颜色 阴影开始方向(默认是从里往外,设置inset就是从外往里);复制代码

    6.边框 border-image: 图片url 图像边界向内偏移 图像边界的宽度(默认为边框的宽度) 用于指定在边框外部绘制偏移的量(默认0) 铺满方式–重复(repeat)、拉伸(stretch)或铺满(round)(默认:拉伸(stretch));

    7.背景 background-clip 制定背景绘制(显示)区域 background-origin background-size

    1.(background-clip: border-box;)默认情况(从边框开始绘制) 2.(background-clip: padding-box;)从padding开始绘制(显示),不算border,,相当于把border那里的背景给裁剪掉! 3.(background-clip: content-box;)只在内容区绘制(显示),不算padding和border,相当于把padding和border那里的背景给裁剪掉!

    8.文字 换行 语法:word-break: normal|break-all|keep-all;、语法:word-wrap: normal|break-word; 超出省略号 text-overflow:clip|ellipsis|string

    文字阴影 语法:text-shadow:水平阴影,垂直阴影,模糊的距离,以及阴影的颜色。

    9.颜色 rgba(rgb为颜色值,a为透明度)

    10.渐变

    11.弹性布局 Flex

    12.盒模型定义 box-sizing:border-box的时候,边框和padding包含在元素的宽高之内!

    box-sizing:content-box的时候,边框和padding不包含在元素的宽高之内!

    13.媒体查询

  41. cookies、sessionStorage和localStorage的区别

    1. 存储大小

      ​ cookie数据大小不能超过4k。

      ​ sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

    2. ​ 有效时间

      ​ localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

      ​ sessionStorage 数据在当前浏览器窗口关闭后自动删除

      ​ cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

    3. 数据与服务器之间的交互方式

      ​cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端 , 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题

      ​ sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存

    4. 作用范围

      1. cookies只能作用于当面目录以及当前的子目录。(同源窗口,子域也可以)

        cookie的作用域和域名有关,和协议以及端口无关。
        1. path属性
          cookie的path属性决定了访问该域名的那些路径时可以携带cookie,当一个tomcat部署多个服务时,将path设置为/,则访问所有tomcat项目时都可以携带。

          domain属性
          cookie的domain属性才是决定了访问哪个域名时可以携带哪些cookie,服务器可以手动设置domian,默认的domain就是请求url中的域名,但是服务器也可以设置当前域名的子域名,但是不允许设置其他域名,如果设置了其他域名,会直接被浏览器丢弃。 例如,访问 www.baidu.com ,则 服务器可以设置cookie的域名为 www.baidu.com、.baidu.com、baike.baidu.com。当baidu.com下的子域名访问时,也可以携带上.baidu.com的cookie,例如当前网站是 www.baike.baidu.com,访问baike的请求时也可以携带 baidu.com的cookie。利用这个特性也可以实现多个相互信任系统之间的单点登录问题。

      2. localStorage是同一浏览器不同标签页之间数据可以共享。(同源窗口)

        默认是不允许跨域的,但是不同域名使用相同的document.domain=“xxx”可以实现

      3. sessionStorage中存储的数据是只能在当前标签页中使用。(同源且同个窗口)

  42. promise

    优点:

    1.解决回调地狱问题 ,有时我们要进行一些相互间有依赖关系的异步操作,比如有多个请求,后一个的请求需要上一次请求的返回结果。

    2.更好地进行错误捕获

    缺点:

    1.无法取消Promise,一旦新建它就会立即执行,无法中途取消。

    2.如果不设置回调函数,promise内部抛出的错误,不会反应到外部。

    3.当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

  43. 介绍一下Vue的响应式系统

    1. 任何一个 Vue Component 都有一个与之对应的 Watcher 实例

    2. Vue 的 data 上的属性会被添加 getter 和 setter 属性

    3. 当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)

    4. data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新

  44. vue怎么进行依赖收集

    1. 每个属性都拥有自己的dep属性,存放依赖他的watcher,当属性变化后会通知自己对应的watcher去更新

    2. 默认在初始化时会调用render函数,此时会触发属性依赖收集 dep.depend

    3. 当属性发生修改时会触发watcher更新 dep.notify()

  45. keep-alive 的作用是什么

    包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

  46. 什么是预加载?

    1. 预加载其实是声明式的 fetch ,强制浏览器请求资源,并且不会阻塞 onload 事件,可以使用以下代码开启预加载
    2. <link rel="preload" href="http://example.com">
    3. 预加载可以一定程度上降低首屏的加载时间,因为可以将一些不影响首屏但重要的文件延后加载,唯一缺点就是兼容性不好
  47. css预处理器的区别(Sass/Less/SCSS)

    总的来说,Less、Sass和SCSS都是强大的CSS预处理器,拥有变量,运算,继承,混合,函数,嵌套的功能,使用两者可以使代码更加的便于阅读和维护。Less具有更简单的语法和支持JavaScript函数,而Sass和SCSS提供了额外的功能,例如条件语句(if else)、循环(for)。选择使用哪个预处理器最终取决于个人偏好和项目要求。无论选择哪个预处理器,它们都有潜力极大地改善您的CSS工作流程。

            Less:是一种动态的样式表语言,可以编译为CSS。它在功能和特性上类似于Sass,但其语法更简单。变量@符号,变量插值@{XXX}

             Sass代表Syntactically Awesome Style Sheets。它是一种预处理器,可以编译为CSS,并为CSS增加了额外的功能。变量($符号),变量插值${XXX}。Sass有两种语法选项:Sass(缩进语法)和SCSS(Sassy CSS)。Sass使用空格缩进来定义代码块,而SCSS具有更传统的CSS语法

  48. scss是什么?在Vue.cli中的安装使用步骤是?有哪几大特性?

    是css的预编译语言。

    使用步骤:

    第一步:先装css-loader、node-loader、sass-loader等加载器模块;
    第二步:在build目录找到webpack.base.config.js,在extends属性中加一个拓展.scss;
    第三步:在同一个文件,配置一个module属性;
    第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”;
    特性:
    可以用变量,例如($变量名称=值);
    可以用混合器;
    可以嵌套;

  49. 什么是 MVVM ?

    MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
    在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
    ViewModel 通过双向数据绑定把 View 层和 Model 层连接起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

  50. vuex是什么?怎么使用?哪种功能场景使用它?

    vue框架中状态管理。在main.js引入store注入。新建一个目录store 。场景有:单页应用中,组件之间的状态,音乐播放、登录状态、加入购物车等。

  51. vuex有哪几种属性?

    有五种,分别是 State、 Getters、Mutations 、Actions、 Modules。

  52. Vuex的State特性
    Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data。

    state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新。

    通过mapState,mapGetters把全局 state 、 getters 映射到当前组件的 computed 计算属性中。

  53. Vuex的Getter特性

    getters 可以对State进行计算操作,它就是Store的计算属性。

    虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用。如果一个状态只在一个组件内使用,可以不用getters。

  54. Vuex的Mutations特性
    我们只能通过mutation去更改state里面的值。mutations需要通过commit来调用其里面的方法,它也可以传入参数,第一个参数是state,第二个参数是载荷(payLoad),也就是额外的参数。
    Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。
    通过mapMutations、mapActions把全局 mutation、 Action映射到当前组件的 methods属性中。
    Vuex所谓的单向数据流:界面—>派发action—>action提交mutation—>mutation更改state—>getters返回最新的state值到界面

  55. 不用Vuex会带来什么问题?

    可维护性会下降,想修改数据要维护三个地方;

    可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;

    增加耦合,大量的上传派发,会让耦合性大大增加,Vue用Component本意就是为了减少耦合,现在这么用,和组件化的初衷相背。

  56. vue-loader 是什么?用途有哪些?

    是解析.vue文件的一个加载器。

    用途:js 可以写es6、style样式可以scss或less、template可以加jade等。

  57. 如何获取dom
    在我们的vue项中,难免会因为引第三库需要操作DOM标签,vue为我们提供了ref属性。 ref 被来给元素或组件注册引信息。引信息将会注册在组件的 $refs 对象上。如果在普通的 DOM 元素上使,引指向的就是 DOM 元素;如果在组件上,引就指向组件实例

  58. iframe的优缺点?

    iframe也称作嵌式框架,嵌式框架和框架页类似,它可以把个页的框架和内容嵌入在现有的页中。
    优点:
    解决加载缓慢的第三内容如图标和告等的加载问题,Security sandbox,并加载脚本,方便制作导航栏
    缺点:
    iframe会阻塞主页的onload事件,即使内容为空,加载也需要时间,没有语意。浏览器的连接池是有限的,太多的iframe会直接影响网站的性能。
    解决方案:
    异步加载iframe

  59. 请说出vue.cli项中src录每个件夹和件的法?
    assets件夹是放静态资源;static是放静态文件(打包不会压缩此文件夹下的内容,直接拷贝放进dist文件中);components是放组件;router是定义路由相关的配置;store是定义公共仓库相关的配置;view视图;app.vue是个应主组件;main.js是入口

  60. vue常的修饰符

    .stop:等同JavaScript中的event.stopPropagation(),防事件冒泡
    .prevent:等同于JavaScript中的event.preventDefault(),防执预设的为(如果事件可取消,则取消该事件,不停事件的进步传播);
    .capture:与事件冒泡的向相反,事件捕获由外到内
    .self:只会触发范围内的事件,不包含元素;
    .once:只会触发一次。
    .native:捕获原生事件
    .sync:类似双向数据绑定,父、子组件修改值,会自动更新

  61. 定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?哪些钩子函数参数?

    全局定义指令:在vue对象的directive法有两个参数,第一个是指令名称,另外一个是对象。组件内定义指令:directives。
    钩子函数:bind(第一次绑定事件时触发)、inserted(元素已插入到父节点的时候触发)、update(被绑定元素更新时调用该函数,可能在其子级更新前调用)、componentUpdated(组件已经更新时调用)、unbind(指令与元素解绑时调用)。
    钩子函数参数:el(dom原素的引用)、binding(value属性)

  62. vue的两个核心点:数据驱动,组件系统

    数据驱动:ViewModel,保证数据和视图的一致性
    组件系统:spa应用类的UI可以看做全部是由组件树构成的

  63. delete和Vue.delete删除数组的区别

    delete只是被删除的元素变成了empty。undefined是未定义,他的元素的键值还是不变。
    Vue.delete直接删除了数组 改变了数组的键值

  64. 如何开发vue插件?

    如果插件是一个对象,必须提供install方法。如果插件是一个函数,它会被作为install方法。调用install方法时,会将Vue作为参数传入。install方法被同一个插件多次调用时,插件也只会被安装一次。
  65. 前端路由和后端路由的区别

    1. 映射关系不同。前端路由是一个路径映射一个组件;后端路由是一个路径映射一个处理本次请求的响应函数。
    2. 前端路由不需要走网络,而后端路由需要走网络。
    3. 前端路由切换页面不会使得网页刷新,后端路由切换页面会导致网页刷新。
    4. 前端路由采用的是客户端渲染,后端路由是服务端渲染。
  66. vue-router的原理和模式
    路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。有hash 和 history 两种实现方式
    hash:hash 是 URL 中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,改变 URL 中的 hash 部分不会引起页面刷新。通过 hashchange 事件监听 URL 的变化,改变 URL 的方式只有这几种:1.通过浏览器前进后退改变 URL;2.通过<a>标签改变 URL;3.通过window.location改变URL。
    history:history 提供了 pushState 和 replaceState 两个方法,这两个方法改变 URL 的 path 部分不会引起页面刷新。history 提供类似 hashchange 事件的 popstate 事件,但 popstate 事件有些不同:1.通过浏览器前进后退改变 URL 时会触发 popstate 事件;2.通过pushState/replaceState或<a>标签改变 URL 不会触发 popstate 事件;3.好在我们可以拦截 pushState/replaceState的调用和<a>标签的点击事件来检测 URL 变化;4.通过js 调用history的back,go,forward方法课触发该事件

  67. 完整的vue-router导航解析流程
    导航被触发。
    在失活的组件里调用beforeRouterLeave离开守卫(组件)可以访问组件  ‘this’。
    调用全局的beforeEach守卫(全局)
    在重用的组件里调用beforeRouterUpdate守卫(2.2+)(组件)可以访问组件  ‘this’。
    在路由配置里调用beforeEnter(单个)。
    解析异步路由组件。
    在被激活的组件里调用beforeRouterEnter(组件)不能获取组件实例  ‘this’  这时组件 this 还没有被创建。
    调用全局的beforeResolve守卫(2.5+)。
    导航被确认。
    调用全局的afterEach钩子(全局)。
    触发DOM更新。
    调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

  68. Vue-router跳转和location.href有什么区别
    使用location.href=/url 来跳转,简单方便,但是刷新了页面;使history.pushState(/url),刷新页,静态跳转;引进router,然后使router.push(/url)来跳转,使了diff算法,实现了按需加载,减少了dom的消耗。其实使router跳转和使history.pushState()没什么差别,因为vue-router就是了history.pushState(),尤其是在history模式下。

  69. params和query的区别
    用法:query要path来引,params要name来引,接收参数都是类似的,分别是this.router .query.name和this.router.params.name。
    url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单点,前者在浏览器地址栏中显参数,后者则不显示。
    注意点:query刷新不会丢失query的数据params刷新会丢失params的数据

  70. RouterLink在IE和Firefox中不起作用(路由不跳转)的问题
    可能是因为IE和Firefox不支持RouterLink指令。
    只a标签,不使button标签法
    使button标签绑定Router.navigate方法

  71. 请说下封装 vue 组件的过程?
    首先,组件可以提升整个项目的开发效率。能够把页抽象成多个相对独立的模块,解决了我们传统项开发的弊端:效率低、难维护、复性等问题。
    然后,使Vue.extend法创建个组件,然后使Vue.component法注册组件。组件需要数据,可以在props中接受定义。组件修改好数据后,想把数据传递给组件。可以采emit方法。

  72. vue mock数据
    在项中尝试了mockjs,mock数据,实现前后端分离开发。
    关于mockjs,官描述的是

    1.前后端分离
    2.不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
    3.数据类型丰富
    4.通过随机数据,模拟各种场景。
    总结:在后端接没有开发完成之前,前端可以已有的接口文档,在真实的请求上拦截ajax,并根据mockjs的mock数据的规则,模拟真实接返回的数据,并将随机的模拟数据返回参与相应的数据交互处理,这样真正实现了前后台的分离开发。
    与以往的模拟的假数据不同,mockjs可以带给我们的是:在后台接未开发完成之前模拟数据,并返回,完成前台的交互;在后台数据完成之后,你所做的只是去掉mockjs:停拦截真实的ajax,仅此已。

  73. vue初始化页闪动问题
    使vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然般情况下这个时间很短暂,但是我们还是有必要解决这个问题的。
    先:在css加上[v-cloak]{display:none;},如果没有彻底解决问题,则在根元素加上style=“display:none;” :style=“{display:block}”

  74. vue更新数组时触发视图更新的法
    push();pop();shift();unshift();splice();sort();reverse();$set

  75. vue常的UI组件库
    Mint UI,element,iview

  76. mint-ui是什么?怎么使?说出少三个组件使法?
    基于vue的前端组件库。
    npm安装,然后import样式和js,vue.use(mintUi)全局引。在单个组件局部引:import {Toast} from ‘mint-ui’。

    组件:Toast(‘登录成功’);
    组件:mint-header;
    组件三:mint-swiper

  77. Vue的router-link在电脑上有,在安卓上没反应怎么解决?
    Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决

  78. Vue2中注册在router-link上事件效解决法
    使@click.native。原因:router-link会阻click事件,.native指直接监听个原事件。

  79. 不同设备间是怎么通信的,IP和MAC地址详解
    1. 引用大佬文章,清晰明了
    2. 文章地址IP地址与Mac地址的关系与区别 - 学习/实践_ip地址和mac地址的关系_宁小法的博客-优快云博客​​​​​​
  80. React组件通信的方式有哪些?

    1. 父子组件通信:使用 props。
    2. 兄弟组件通信:状态提升到父组件。
    3. 跨层级通信:使用 Context。
    4. 全局状态共享:使用 Redux 等工具
  81. 简述React的生命周期

    React的生命周期主要分为三个阶段:MOUNTING、RECEIVE_PROPSS. UNMOUNTING
    组件挂载时(组件状态的初始化,读取初始state和props以及两个生命周期方法,只会在初始化时运行一
    次)
    componentWillMount会在 render之前调用 (在此调用setSttate,是不会触发re-render的,而是会进行
    state的合并。因此此时的this.state不是最新的,在render中才可以获取更新后的this.state。)
    componentDidMount会在 render之后调用
    组件更新时(组件的更新过程是指父组件向下传递props或者组件自身执行setState方法时发生的一系列更新
    的动作)
    组件自身的state更新,依次执行
    shouldComponentUpdate(会接收需要更新的 props和state,让开发者增加必要的判断条件,在其需
    要的时候更新,不需要的时候不更新。如果返回的是false,那么组件就不再向下执行生命周期方法。)
    component WillUpdate
    render(能获取到最新的this.state)
    componentDidUpdate(能获取到最新的this.state)
    父组件更新props而更新
    componentWillReceiveProps(在此调用 setState,是不会触发re-render的,而是会进行state的合
    并。因此此时的this.state不是最新的,在render中才可以获取更新后的this.state
    shouldComponentUpdate
    component WillUpdate
    render
    componentDidUpdate
    组件卸载时
    componentWillMount(我们常常会在组件的卸载过程中执行一些清理里方法,比如事件回收、清空定时器
    新版的生命周期函数增加了getDerivedStateFromProps,这个个生命周期其实就是将传入的props映射到state中。
    在React 16.4之后,这个函数每次会在 render之前调用,
    getDerivedStateFromProps的作用是
    无条件的根据prop来更新内部state,也就是只要有传入prop值,就更新state
    只有prop值和state值不同时才更新state值。
  82. React事件机制和原生DOM事件流有什么区别

    react中的事件是绑定到document上面的,而原生的事件是绑定到dom上面的,因此相对绑定的地方来说,dom上的事件要优先于document上的事件执行。
  83. Redux工作原理

    Redux 是 React 的第三方状态管理库,创建于上下文API存在之前。它基于一个称为存储的状态容器的概念,组件可以从该容器中作为 props 接收数据。更新存储区的唯一方法是向存储区发送一个操作,该操作被传递到一个reducer中。reducer接收操作和当前状态,并返回一个新状态,触发订阅的组件重新染。
  84. React-Router工作原理?react-router-dom有哪些组件

    路由器组件,路由匹配组件,导航组件
    react-router 的依赖库history
    BrowserHistory:用于支持 HTML5 历史记录 API 的现代 web 浏览器(请参阅跨浏览器兼容性)
    HashHistory:用于旧版web浏览器
    MemoryHistory:用作参考实现,也可用于非 DOM 环境,如 React Native 或测试
    
    BrowserHistory: pushstate、replacestate6 
    HashHistory:location.hash、location.replace

  85. Reacthooks解决了什么问题?函数组件与类组件的区别

    Hooks 解决了我们五年来编写和维护成千上万的组件时遇到的各种各样看起来不相关的问题。无论你正在学习React,或每天使用,或者更愿尝试另一个和 React 有相似组件模型的框架,你都可能对这些问题似曾相识。在 React 16.8版本(引入钩子)之前,使用基于类的组件来创建需要维护内部状态或利用生命周期方法的组件(即componentDidMount 和 shouldComponentUpdate )。基于类的组件是 ES6 类,它扩展了 React 的Component 类,并且至少实现了render()方法。
  86. SetState是同步还是异步的,setState做了什么

    在React中,setstate()函数通常被认为是异步的,这意味着调用setState()时不会立刻改变react组件中state的值,setState通过触发一次组件的更新来引发重汇,多次setState函数调用产生的效果会合并调用 setstate时,React会做的第一件事情是将传递给 setState的对象合并到组件的当前状态。这将启动一个称为和解(reconciliation)的过程。和解(reconciliation)的最终目标是以最有效的方式,根据这个新的状态来更新UI。为此,React将构建一个新的 React元素树(您可以将其视为 U 的对象表示)。
    一旦有了这个树,为了弄清 U如何响应新的状态而改变,React 会将这个新树与上一个元素树相比较
  87. 什么是fiber,fiber解决了什么问题

    React15 的 stackReconciler 方案由于递归不可中断问题,如果 Diff 时间过长(JS计算时间),会造成页面UI的无响应(比如输入框)的表现,vdom 无法应用到 dom 中。
    为了解决这个问题,React16 实现了新的基于 requestIdleCallback 的调度器(因为
    requestIdleCa1lback 兼容性和稳定性问题,自己实现了 polyfi11),通过任务优先级的思想,在高优先级
    任务进入的时候,中断reconciler。
    为了适配这种新的调度器,推出了FiberReconciler ,将原来的树形结构(vdom)转换成 Fiber 链表的形式(child/sibling/return),整个 Fiber 的遍历是基于循环而非递归,可以随时中断。
    更加核心的是,基于 Fiber 的链表结构,对于后续(React 17lane 架构)的异步渲染和(可能存在的)worker 计算都有非常好的应用基础
  88. React中在哪捕获错误?

    class ErrorBoundary extends React.Component<
      ErrorBoundaryProps,
      { hasError: boolean; errorInfo: React.ReactNode }
    > {
      state = { hasError: false, errorInfo: '' };
    
      static getDerivedStateFromError(error: Error) {
        return { hasError: true, errorInfo: error.message };
      }
    
      componentDidCatch(error: any, errorInfo: ErrorInfo) {
        console.error('🐞🐞🐞------->', error, errorInfo);
      }
    
      handleRetry = () => {
        this.setState({ hasError: false, errorInfo: null });
      };
    
      render() {
        if (this.state.hasError) {
          return (
            <Result
              status="error"
              title="出错了!"
              subTitle={import.meta.env.MODE === 'development' && this.state.errorInfo}
              extra={
                this.props.retry && (
                  <XZLButton type="primary" onClick={this.handleRetry}>
                    重试
                  </XZLButton>
                )
              }
            />
          );
        }
        return this.props.children;
      }
    }

  89. react如何做到和vue中keep-alive的缓存效果

  90. React如何做路由监听

  91. React有哪几种方式改变state

  92. React有哪几种创建组件方法

  93. react中props和state有什么区别

  94. React中keys的作用是什么?

  95. React中refs的作用是什么?

  96. React diff原理

  97. 受控组件和非受控组件有什么区别?

  98. Redux和Vuex有什么区别,它们的共同思想?

  99. 循环渲染中为什么推荐不用index做key?

  100. React如何避免使用context的时候,引起整个挂载节点树的重新渲染

  101. useState的原理是什么,背后怎么执行的

  102. 如何避免使用context的时候,引起整个挂载节点树的重新道【热

  103. UseEffect依赖为空数组与 componentDidMount区别

  104. UseEffect钩子的工作原理是什么

  105. React是如何处理组件更新和渲染的?

  106. forwardsRef作用是啥,有哪些使用场景

手写系列(引用大佬)

  1. 文件下载(blob)
    /**
     * 检验返回数据是否是文件流
     * @param {*} res 
     * @returns 
     */
    export function isStream(res){
      console.log(6666,res.headers['content-type'],res);
      return  res.headers['content-type'].includes('application/octet-stream')
    }
    
    /**
     * 获取文件名称
     * @param {*} res 
     */
    export function getFileName(res){
      // /* 截取头部获取文件名 utf8转中文 */
      let str = res.headers['content-disposition']
      return decodeURI(str.split('=')[1].split('.xls')[0])
    }
    
    /**
     * 导出文件 
     * (bold文件流方式导出)
     * @param {*} res 
     * @param {*} fileName 
     */
    export function download(res, fileName) {
        var blob = new Blob([res.data])
        const reader = new FileReader()
        reader.readAsDataURL(blob)
        reader.onload = (e) => {
          const a = document.createElement('a')
          a.download = `${fileName}.xls`
          a.href = e.target.result
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
        }
      }

前端面试题及答案整理(2022最新版)_程序员·小季的博客-优快云博客_前端进阶面试题

前端常见面试题 前端一些常见面试题 阅读详情

相关推荐

前端实习面试题分享

因为马上要准备找实习了,还不知道面试官要问啥。所以从B站上找到一位愿意分享面试经历的UP主,耗时一天,把她遇到的所有面试题都分类并且手敲了出来,在这里我再分享给大家。括号内是她提供的一些参考答案,基本没错。由于她面的公司比较多,有的问题会重复多次,我做了统计并标注了出来,希望能对大家有所帮助~ HTML h5新增的标签有哪些?为什么要加强语义化? (吉利) three times 行内元素,块级...

qq_40407724的博客 2070

javascript中setTimeout函数使用案例

alert("start"); var t = true; window.setTimeout(function(){ t = false; }, 1000); while(t){ } alert("end"); 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也

1169

Ubuntu 24.04中文输入法终极指南:从安装到疑难排解

本文是Ubuntu 24.04中文输入法的完整指南,详细介绍了如何通过图形界面或命令行安装和配置Intelligent Pinyin输入法。内容涵盖IBus框架的运作原理、输入法快捷键调校、模糊音设置,并重点解决了Qt应用无法输入中文的疑难问题,最后提供了Fcitx5备选方案及常见故障的排解方法。

weixin_29294975的博客 1240

js面试题(持续更新)

js面试题 new操作符具体干了什么 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型 属性和方法被加入到 this 引用的对象中 新创建的对象由 this 所引用,并且最后隐式的返回 this var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj) javascript对象的几种创建方式 工厂模式 构造函数模式 原型模式 混合构造函数和原型模式 动态原型模式 寄生构造函数模式 稳妥构造函数模式 哪些操作会

豪哥的博客 1692

企业级 Agent 在 K8s 上的运行模型

Kubernetes├── Agent Orchestrator(控制面)├── Agent Runtime Pods(执行面)├── Graph DSL(流程层)├── Tool Services(能力层)K8s(调度)+ Graph(流程)+ Agent(决策)+ Tool(执行)+ Guard(治理)

一起修行,不孤单。这里有编程语言、开发工具、学习方法论和踩坑笔记。用简单的话说复杂的事,陪你从小白到进阶。周更干货,欢迎一起成长! 1171

STM32F407 UART4串口DMA收发实战:告别频繁中断,用空闲中断+DMA搞定不定长数据

本文详细介绍了STM32F407 UART4串口结合DMA和空闲中断实现高效不定长数据收发的实战方案。通过DMA硬件级数据搬运和空闲中断智能帧检测,显著降低CPU占用率,提升通信效率,适用于工业传感器数据采集和智能设备通信场景。

weixin_42631411的博客 154

前端每日一面01

1、说一下innerHTML 与 innerText的作用与区别? 作用:都可以获取或者设置元素的内容 区别:innerHTML可以解析内容中的html标签 innerText不能解析内容中的html标签 2、JavaScript 由以下三部分组成: 1)、ECMAScript(语法部分):JavaScript 语言基础 2)、DOM(文档对象模型):规定了访问 HTML 和 XML 的方法...................

My dream 773

使用这个算法我可以实现英雄联盟里英雄的走位|Java 开发实战

A算法,A(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。 基本概念 首先在大学我们遇到最多的算法Dijkstra、Floyd、广度搜索、深度搜索。关于这些算法我们以后再慢慢的研究,今天的重点在A算法上。A算法是一种启发式算法。与上述几种算法不同的是A*算法在考虑起始节点的同时还会考虑到目标节点的代价。 在A*算法中我们给每个节点都定义一些属性。最基本的就是下文提到的三基数-这里的三基数是我自己定义.

Java进阶营 312

函数接收一个列表参数,返回该列表的均值方差、标准差

请编写一个函数,该函数接收一个列表参数,返回该列表的均值方差、标准差,最后在主程序中测试该函数。 统计学里最基本的概念就是样本的均值、方差、标准差。首先给定一个含有N个样本的集合,下面给出这些概念的公式描述。 均值表示的信息是有限的,而标准差描述的是样本集合的离散程度。 以两个集合[0, 8, 12, 20]和[8, 9, 11, 12]为例,它们的均值都是10,但显然两个集合的差别是很大的,计算两者的标准差。前者是8.3,后者是1.8,显然后者较为集中,故其标准差较小,标准差描述的就是.

qq_47112287的博客 3752

SAP Word 模板与 ABAP XML 数据流合并机制深度解析

Office Open XML 标准把一个.docx拆分成多个部件(document.xml、customXml\item1.xml 等),天然支持命名空间与 XPath;Word 在渲染时,会扫描<w:sdt>(结构化文档标签)与来确定绑定关系;在 ABAP 端,通过简单字符串替换与 XSLT 变换即可完成数据灌入,无需 COM Automation,安全且易于调试。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 371

mojoPortal 路径穿越漏洞复现(CVE-2025-28367)(附脚本)

 在 mojoPortal CMS 版本 <=2.9.0.1 中发现了一个导致 ViewState 反序列化的目录遍历漏洞。通过利用此问题,未经身份验证的攻击者可以泄露 Web 根目录中的敏感文件,包括应用程序的文件。此配置文件包含用于验证和解密 ViewState 数据的文件。知道此密钥后,网络攻击者可以构建恶意 ViewState 有效负载,从而导致在底层服务器上执行远程代码。(CVE-2025-28367)

iSee857的博客 500

Python学习笔记之函数(一)

1、什么是函数:函数是带名字的代码块,用于完成具体的工作。 需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用执行该任务的函数。 2、定义函数,函数定义使用关键字def,直接附上示例代码: #函数定义 def test(): print("测试函数定义"); #调用函数 test(); 其中定义函数test(),方法体就需进行代码的缩进,调用函数直接用...

茕夜 1925

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图、天地图)

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图)

1万+

【前端】前端面试题

闭包(Closure) 是指一个函数能够访问并记住其外部作用域中的变量,即使外部函数已经执行完毕。闭包由两部分组成: 2. 闭包的核心原理 作用域链:函数在定义时,会记住自己的词法环境(即外部作用域)。当内部函数访问变量时,会沿着作用域链向上查找。 变量持久化:闭包使得外部函数的变量不会被垃圾回收,因为内部函数仍持有对它们的引用 3. 闭包的常见用途 3.1 私有变量封装 通过闭包隐藏内部变量,仅暴露操作接口: 3.2 函数柯里化(Currying) 将多参数函数转换为单参数链式调用: 3.3 事件处

zjb313452的博客 1万+

合肥工业大学操作系统实验9

依据操作系统课程所介绍的页面置换算法与动态内存分配的原理,本实验的目的是掌握OPT、FIFO、LRU、LFU、Clock等页面置换算法;掌握可用空间表及分配方法;掌握边界标识法以及伙伴系统的内存分配方法和回收方法。从而深入理解操作系统的内存管理。从而加深对教材上页面置换算法与动态内存分配的理解。

Martin-share的博客 1094

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

96道前端面试题+前端常用算法

这篇文章主要分享一些收集整理的面试题,希望能对大家有所帮助。 字节 一面: 1,说一下浏览器缓存 2,cookie 与 session 的区别 3,浏览器如何做到 session 的功能的。 4,解释一下:csrf 和 xss 5,怎么防止 csrf 和 xss 6,跨域的处理方案有哪些 7,CORS 是如何做的? 8,对于 CORS ,Get 和 POST 有区别吗? 9,了解 HTTPS 的过程吗? 10,es module 和 commonjs 的区别 11,react 里如何做动态加载 12,动.

QXXXD的博客 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

前端(百度,阿里,腾讯)面试题收藏!269页前端大厂面试题宝典分享!

前言 文章分享收集整理的百度,阿里,腾讯前端(实习)面试题。还有《【269页】前端大厂面试题宝典》,主要内容概括:HTML,CSS,JavaScript,HTTP,TCP协议,浏览器,Vue,数据结构与算法。 百度(实习) position bind、apply,call 手写bind BFC csrf 跨域 diff算法 虚拟DOM 单位(像px,rem,em,vw等) SSR(怎么实现) ua和媒体查询 OSI七层模型 浏览器缓存机制 怎么实现在项目中使用强缓存,协商缓存 Event loop let

QXXXD的博客 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

前端三年到五年面试题分享

今天给大家分享一些三年到五年前端的面试题 1. 达达京东到家 笔试: 都是些基础选择题,考察计算机网络,事件循环机制,闭包,this 这些。 一面: 三次握手和四次挥手详细介绍 TCP 有哪些手段保证可靠交付 URL 从输入到页面渲染全流程 如何预防中间人攻击 DNS 解析会出错吗,为什么 ES6 的 Set 内部实现 如何应对流量劫持 算法:top-K 问题,分成 top-1,top-2,to...

吴小迪的博客 4万+

【Uniapp】前端面试题

因为我个人技术栈里有Uni-app框架,所以会被问到关于Uni-app的知识点,需要的家人可以看看。 文章头部有所有的分类的链接,方便大家跳转。

Una的博客 4862

身为三本的我就是凭借这些前端面试题拿到百度京东offer的,前端面试题及答案

点进来之后你的噩梦就要来了,接下来你要面对上百道面试题,那么,如果你—— 是个小白菜: 推荐使用2~3周的时间来消化接下来的面试题, 遇到不会的专业名词请立刻去搜; 文章中只是简答,如果想要详细了解的话还需要你自觉去搜索 如果你是个大神: 好叭先给您拜个早年,大哥大嫂过年好。 请温柔点黑我。 顺便,如果有错误的地方请各位一定要指出,免得误导更多人。 接下来的题我会根据重点程度使用⭐来标记,⭐越多标明越重点,满星是5颗星 ok,你准备好了吗?咱们开始吧! JS 数据类型 面试官:JavaSc

晟小明的博客 22万+

10道高频Qiankun微前端面试题快问快答_微前端qiankun面试题

qiankun 是一个基于 single-spa 的微前端实现库,可以帮助我们将多个独立的前端应用整合成一个整体,并且可以独立开发、独立部署、独立运行。

2401_89821876的博客 1838

来自大厂 300+ 道前端面试题大全附答案(整理版)+前端常见算法面试题~~最全面详细

进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份腾讯、字节跳动、百度、阿里等一线互联网公司面试题大全,其中概括的知识点(HTML,CSS,JS,React,Vue,NodeJS,互联网基础知识)

weixin_56134381的博客 1万+

前端开发面试题

本文收集总结了一些前端面试题,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习、透彻学习,形成自己的知识链。万不可投机取巧,临时抱佛脚只求面试侥幸混过关是错误的!也是不可能的!不可能的!不可能的! 前端还是一个年轻的行业,新的行业标准, 框架, 库都不断在更新和新增,正如赫门在2015深JS大会上的《前端服务化之路》主题演讲中说的一句话:"每18至24个月,前端都会难一倍",这些变化使前端的能力更加丰富、创造的应用也会更加完美。所以关注各种前端技术,跟上快速变化的节奏,也是身为一个前端程序员必.

嘿嘿 1044

前端面试题全面整理

本篇文章整理总结了一些前端面试题,涵盖面很广,并且面的都是知名大厂,所以这些题还是很有代表性的,都掌握以后一面基础面应该没什么问题,二面也能应付大半,奉上: css相关 1. 万能居中 1.margin: 0 auto;水平 2.text-align: center;水平 3.行高,垂直 4.表格,center,middle;水平垂直 5.display:table-cell;模拟表格,all 6.绝对定位,50%减自身宽高 7.绝对定位,上下左右全0,margin:auto 8.绝对定位加相对定位。不.

weixin_37739550的博客 6864
上一篇: vue项目使用vue-quill-editor,光标位置控制(已解决)
下一篇: 前端er必知的web安全性
jsPao
博客等级 码龄7年 549粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值