前端面试题个人总结( 二 )(持续更新)

155 阅读8分钟

image.png

前言

本人三年前端小菜鸡,苦逼搬砖狗,这是一个用于记录面试多年遇到的面试题都是比较基础的问题,第一次写顺序比较混乱没什么章法,仅供参考、欢迎指正

axios和ajax、fetch的区别?

1、 axios和ajax都是对本身XHR的封装,但ajax本身是针对MVC的编程,不符合现在MVVM的浪潮而且用的话却要引入整个jQuery不合理

2、axios是从node.js创建请求,支持Promise API,客户端支持防止CSRF,提供了一些并发请求的接口

3、符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里更好更方便的写法更加底层,提供的API丰富(request, response)脱离了XHR,是ES规范里新的实现方式

1)fetchtch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理

2)fetch默认不会带cookie,需要添加配置项

3)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费

4)fetch没有办法原生监测请求的进度,而XHR可以

为什么要用axios?因为axios是一个基于Promise用于浏览器和nodeJS的http客户端

重构和重绘

元素宽高的改变会造成重构reflow,颜色改变会造成重绘repaint

什么是回调地狱怎么解决?

大量的使用异步回调例如ajax/axios就会造成回调地狱,还有就是JS中,为了实现某些逻辑写出层层嵌套的回调函数,如果嵌套过多,会极大影响可读性和逻辑,这种情况也被称为回调地狱 一个异步请求套着一个异步请求,一个异步请求依赖于另一个的执行结果,使用回调的方式相互嵌套,这会导致代码很丑陋,不方便后期维护

解决方法

async await ;或promise对象(then)推荐async await搭配promise

  • async 表示函数里有异步操作,它保证函数的返回值为 promise
  • await 表示紧跟在后面的表达式需要等待结果。
  1. 是一种编写异步代码的新方法。之前异步代码的方案是callback和promise。
  2. 建立在 promise 的基础上,与promise一样也是非阻塞的。
  3. async/await 让异步代码看起来、表现起来更像同步代码。这正是其威力所在。

什么是虚拟DOM?以及它的优缺点

所谓虚拟DOM,其实就是使用JS对象来构建DOM树; 虚拟DOM以JS结构的形式存在,计算性能会比较好,而且由于减少了实际DOM的操作次数,性能会有很大的提升

真实DOM的解析流程

创建DOM树——创建styleRules——创建render树——布局layout——绘制painting

XSS攻击

就是利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序,这些网页程序通常是JS,攻击成功后,攻击者可能会得到包括但不限于更高的权限如执行一些操作、私密 网页内容、会话和cookie等各种内容

如何防范

1、不信任用户提交的任何内容,对用户提交内容进行可靠的输入验证,任何内容输出到页面之前都必须加以en-code

2、实现session标记(session tokens)验证码或者http引用头检查,以防止功能被第三方网站执行

3、 cookie防盗

Cookie如何防范XSS攻击

XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入JS脚本,为了减轻这些攻击,需要在http 头部配上set-cookie:

  • httponly这个属性可以防止XSS,它会禁止JS来访问cookie
  • secure这个属性告诉浏览器仅在请求为HTTPS的时候发送cookie

meta标签

meta标签共有两个属性

1、http-equiv属性:相当于http的头文件作用,它可以向浏览器传回一些有用的信息,以帮助正确显示网页内容 <meta http-equiv=”参数” content=”参数变量值”>

2、name属性 name主要是描述网页,对应值content,content的主要内容就是便于搜索引擎机器人的查找信息和分类信息用的。

meta标签的一个很重要的功能就是设置关键字,来帮助你的主页被各大搜索引擎登录,提高网站的访问量 在这个功能中,最重要的就是对keywords和description的设置。因为按照搜素引擎的工作原理,搜索引擎首先派出机器人自动检索页面中的keywords和description,并将其加入到自己的数据库,然后再根据关键字的密度将网站排序

<meta name=”keywords” content=”网页,网页制作,网页特效,建站指南,教程下载,动画制作,网页教学,网页素材,视频教程,技术论坛,免费空间,免费域名”>
<meta name=”description” content=”网页教学网,专业的网页教学网站”>

ES6新特性

  1. 不一样的变量声明:const和let,两者都为块级作用域,不会声明提前
  2. 字符串模板:基本的字符串拼接用$()es6反引号(‘’)直接搞定
  3. 箭头函数:不需要用function来创建函数,省略return关键字,继承当前上下文的this
  4. 对象和数组解构

ES7-10新特性

image.png

ES12: weakset、weakmap

特性详解: segmentfault.com/a/119000003…

如何优化页面加载速度?

  1. 减少http请求
  2. 使用CDN(内容发布网络)
  3. 将样式表放在头部
  4. 将脚本放在底部
  5. 使用外部的js和css(使用外部的话,浏览器就有可能缓存它们,从而加载的时候直接使用缓存), get请求有缓存

webpack常用插件?

  • html-webpack-plugin:将一个页面模板打包到dist目录下,生成index.html
  • script-ext-html-webpack-plugin:内联
  • speed-measure-webpack-plugin:可以看到每个loader和plugin的耗时情况。
  • webpack-dev-server:自动编译(热部署),浏览器端就会即时展示新的应用效果

前端与安卓交互的方法

1、JSBrige

2、赋给window

3、cordova

cookie、localstroge、session之间的区别?

  • cookie一般由服务器生成,可设置失效时间,如果是在浏览器生成,默认关闭后失效4kb,用document。cookie来调用
  • localstroge除非被永久清除,否则永久保存5m
  • session仅在当前会话有效,关闭页面或浏览器后被清除

小程序的生命周期

  • onLaunch:首次打开小程序会触发,全局只触发一次
  • onShow:初始化完成会触发监听小程序的显示
  • onHide:从前台进入后台会触发
  • onError:发生脚本错误或者api调用失败
  • onload:首次进入页面加载触发
  • onReady:页面首次渲染完触发

css的link和@import的区别?        

link是HTML提供的标签不仅可以加载css文件还可以定义RSS、rel连接属性,加载页面是link标签引入的css被同时加载

@import引入的css将在页面加载完毕后被加载 ;JS操作DOM插入link标签来改变样式,由于dom方法是基于文档的,所以无法使用@import的方式插入样式

iframe的缺点

定义:iframe元素会创建包含另一个文档的内联框架 提示:可以将提示文字放在之间,来提示某些不支持iframe的浏览器

  • 缺点: 1、会阻塞主页面的onload事件

2、搜索引擎无法解读这种页面,不利于SEO

3、iframe和主页面共享连接池,而浏览器对相同区域有限制所以会影响性能

为什么 vue 组件中的 data 是函数而不是对象

在一个项目中,组件可以有多个,每一个组件均可当作一个构造器,注册组件的本质其实就是构造器的引用。如果直接使用对象,他们的内存地址是一样的,一个数据改变了其他也改变了,这就造成了数据污染,如果使用函数的话,会形成一个全新的作用域,这样data中的数据不会相互影响,从而避免数据污染。但由于根实例只有一个,所以不存在数据污染这种情况,也就可以使用对象了。

宏任务和微任务

宏任务task,每次执行的代码就是一个宏任务(script、settimeout、setinterval、UI交互事件)

微任务microtask,可以理解为当前task执行结束后立即执行的任务,所以它的响应速度会比宏任务更快,包含的有(promise.then,object.observe,process.nextTick)

image.png

计算当前时间点所在的一周开始时间戳及结束时间戳,备注:北京时间,以周一为一周的第一天

function fun_date(aa)

{
var date1 = new Date(),

time1=date1.getFullYear()+"-"+(date1.getMonth()+1)+"-"+date1.getDate();//time1表示当前时间zd

var date2 = new Date(date1);

date2.setDate(date1.getDate()+aa);       
var time2 = date2.getFullYear()+"-"+

(date2.getMonth()+1)+"-"+date2.getDate();
console.log(time1,time2,date1,date2)
}

fun_date(7);

字符串替换

 将字符串"My Name is${name},I like ${hobby}"

      按照对象数据:{name:"Tom",hobby:"Coding"}

      替换为:"My Name is Tom, I like Coding"


function format() {
        if(arguments.length == 0) return this;
        var obj = arguments[0];
        var s = this;
        for(var key in obj) {
            s = s.replace(new RegExp("\$\{" + key + "\}", "g"), obj[key]);
        }
        return s;
    }
 var data = {
        name:"张三",
        age:23,
        sex:"男"
    }
    var text = "我叫${name},我今年${age}岁,我的性别是${sex}!".format(data);
    console.log(text);

sleep函数

function sleep(delay) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime() - start < delay) {
    continue;
  }
}

function test() {
  console.log('111');
  sleep(2000);
  console.log('222');
}

test()

事件流

事件流分为2种,捕获事件流冒泡事件流。

  1. 捕获事件流从根节点开始执行,一直往子节点查找执行,直到查找执行到目标节点。

  2. 冒泡事件流从目标节点开始执行,一直往父节点冒泡查找执行,直到查到根节点

数组去重

const arr = [1,2,2,2,4,5,7,7,8];

1、Array.from(new Set(arr)); 

2、

 

let arrResult = arr.reduce((pre,cur) => {
    if(!pre.includes(cur)) {
        pre.push(cur)
    }
    return pre;
}, [])

3、[...new Set(arr)]

判断类型

ECMAScript 中确定一个变量的类型有 5 种方法:typeof 运算符、instanceof 运算符、Array.isArray() 方法、constructor 属性、Object.prototype.toString() 方法。

1、typeof 在判断字符串、数值、布尔值和undefined 和 函数的类型是很好用,但是对象、null、数组 等就不好用了。

2、instanceof 和 constructor 一般用于确定指定变量是否为某种个对象的实例。(返回布尔值)

3、Array.isArray(variable) 方法用于判断指定变量是否为数组,可以解决框架的问题

4、Object.prototype.toString.apply() 方法,完美判断变量类型的方法。 Object.prototype.toString.apply(variable),返回 [object Xxx]

Set和Map的区别

Set:

  • 成员唯一,无序且不重复[value,value],
  • 键值与键名是一致的(或者说只有键值,没有键名)
  • 可以遍历,方法有:add,delete,has

WeakSet:

  • 成员都是对象。
  • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏。
  • 不能遍历,方法有add、delete、has。

Map:

  • 本质上是键值对的集合,类似集合。
  • 可以遍历,方法很多可以跟各种数据格式转换。

WeakMap:

  • 只接受对象作为键名(null除外),不接受其他类型的值作为键名。
  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的。
  • 不能遍历,方法有get、set、has、delete。

React合成事件理解

如果DOM上绑定了过多的事件处理函数,整个页面响应以及内存占用可能都会受到影响。React为了避免这类DOM事件滥用,同时屏蔽底层不同浏览器之间的事件系统差异,实现了一个中间层——SyntheticEvent。

1.当用户在为onClick添加函数时,React并没有将Click时间绑定在DOM上面。
2.而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装交给中间层SyntheticEvent(负责所有事件合成)
3.所以当事件触发的时候,对使用统一的分发函数dispatchEvent将指定函数执行。 React合成事件的冒泡并不是真的冒泡,而是节点的遍历。

vue-cli生成的文件结构

image.png

柯里化

柯里化是将一个多参数的函数转换成多个单参数的函数,但是现在我们不仅可以传入一个参数,还可以一次传入两个参数,甚至更多参数……这看起来更像一个柯里化 (curry) 和偏函数 (partial application) 的综合

强制缓存和协商缓存

缓存状态码请求服务器
强缓存200(from memory cache)否,直接从缓存取
协商缓存304是,通过服务器告知浏览器缓存是否可用

HTTP Cache 是我们开发中接触最多的缓存,分为强缓存和协商缓存,一般做了强缓存,只有在强缓存失效了才走协商缓存。

  • 强缓存:浏览器第一次请求时直接缓存资源,缓存本地,第二次查看资源是否过期,没过期则直接使用资源,过期则重新请求。
  • 协商缓存:浏览器第一次请求缓存且保存缓存的标识和时间,重复请求,浏览器会去请求服务器验证资源是否更新,服务器根据缓存标识进行判断,没有失效则使用缓存,此时返回的是 304,通知客户端可以使用缓存数据。如果失效则重新发送资源。

CommonJS和ES6模块的区别

  • CommonJS模块是运行时加载,ES6模块是编译时输出接口
  • CommonJS模块输出的是一个值的复制,ES6模块输出的是值的引用
  • CommonJS加载的是整个模块,即将所有的方法全部加载进来,ES6可以单独加载其中的某个方法
  • CommonJS中this指向当前模块,ES6中this指向undefined
  • CommonJS默认非严格模式,ES6的模块自动采用严格模式