前端面试系列(二)
如何理解执行上下文
每一段js代码的执行之前都会创建一个上下文环境
JavaScript执行上下文是指代码运行环境。
执行上下文有三种:
- 全局执行上下文
- 函数执行上下文
- eval执行上下文
如何理解作用域链
JavaScript代码执行前会创建上下文环境(包含变量、作用域链、this)
也就是从当前环境向父级一层层的查找变量的过程,这个链就是作用域链。
实例:
1 | var name = 'wang' |
以上代码:执行 hello()
的时候,会先在hello()的作用域内查找变量 name
,如果没有找到则去hello()的父级作用域查找。
如何理解原型链
每个函数都有一个 prototype
属性,每个函数实例对象都有一个 __proto__
属性,这个属性指向函数的 prototype
。
当我们访问实例对象的属性或者方法的时候,会先从自身构造函数中查找,如果找不到就通过 __proto__
去原型中查找,这个查找过程所访问的链就是原型链。
实例:
1 | // parent class |
上面会先查找 lee
再查找 Human
,找不到再往上找。
闭包
闭包就是定义在一个函数内部的函数,这样就可以使用内部函数访问到外部函数中的局部变量。
实例:
正常情况下无法访问到函数内部的局部变量:
1 | function f1() { |
输出:
1 | undefined |
使用闭包:
1 | function f1() { |
输出:
1 | mason |
总结:
由于在 JavaScript 中,只有函数内部的子函数才能读取内部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包最大的特点,就是它可以“记住”诞生的环境,比如 f2
记住了它诞生的环境 f1
,所以从 f2
可以得到 f1
的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
继承有哪些方法
- 原型继承
- 构造继承
- 实例继承
- call(),apply()
- ES6的class extends
深拷贝、浅拷贝
javascript的数据类型总体分为基本类型和引用类型。
基本类型保存值,引用类型保存指针。
浅拷贝:共用一个引用地址,方法有直接对象复制、 Object.assign
。
深拷贝:创建新的内存地址,方法有:先 JSON.stringify
转化为字符串再 JSON.parse
,还有深度递归遍历。
如何判断一个对象是数组
方法:
1 | Object.prototype.toString.call([]) |
输出:
1 | "[object Array]" |
数组有哪些方法
- push()
- pop()
- shift()
- unshift()
- concat()
- join()
- reverse()
- sort()
- map()
- forEach()
- filter()
- indexOf()
- includes()
- slice()
- splice()
slice()和splice()的区别:
slice():截取数组,参数有起始点和结束点,不改变原数组,返回新数组。
splice():删除,参数有起始点、长度、待插入的元素。
DOM常用操作
创建节点:
- createElement
- createTextNode
- createDocumentFragment
修改节点:
- appendChild
- insertBefore
- replaceChild
CSS清除浮动的方法有哪些
- 父元素设置高度,手动撑开
- 浮动元素结尾添加空标签,设置空标签clear: both
- 父元素设置overflow: hidden
- 父元素添加伪类:after和zoom
CSS选择器优先级
!important > 内联样式 > id选择器 > 类选择器/属性选择器/伪类 > 元素选择器
CSS三列布局
- 浮动布局
左边区域 float: left;
,右边区域 float: right;
,中间区域设置 margin-left
和 margin-right
。
1 | <div class="layout"> |
1 | .layout { |
- 定位布局
三列布局的父元素设置 position: relative;
,左边区域 position: absolute;
并同时设置 left
,右边区域 position: absolute;
并同时设置 right
。
中间部分设置 position: absolute;
并设置 margin-left
和 margin-right
。
- flex布局
1 | .layout_left { |
谈一下flex布局
flex是弹性布局。
包含flex-container和flex-item。
常用属性:flex-direction、flex-wrap、justify-content、align-items。
水平居中 justify-content:center 水平两头居中 justify-content:space-between 垂直居中 align-items:center。
什么是盒模型
内容区、 padding
、 border
、 margin
分为IE盒模型和w3c盒模型
box-sizing: border-box;
box-sizing: content-box
IE盒模型的 width
包含了content、 border
、 padding
。
transition动画和animation的区别
transition用于做简单的过渡效果。
animation可以做复杂的效果。
h5自适应方案
使用 rem
,rem是根据 html
的 font-size
来设置的。
call(), apply(), bind()
作用都是改变函数的作用域。
call()
, apple()
可以直接执行, bind()
不会立刻执行。
call()
单个传参, apply()
用数组传参。
观察者和发布订阅的区别
发布订阅有调度中心,
浏览器解析渲染页面的过程
- 浏览器解析html文档并生成DOM树。
- 浏览器解析CSS生成CSSOM树。
- DOM和CSSOM关联,生成渲染树。
- 根据渲染树进行布局。
- 根据渲染树进行绘制。
- 将图像信息发送给GPU,最终显示在显示器上。
谈一谈EventLoop事件循环
JavaScript本身是单线程,也就是同一时刻只能干一件事,JS任务包含了同步任务和异步任务,遇到执行函数会将其放入调用栈(先进后出)中,遇到setTimeout/setInterval等异步任务时,会把它放入到消息队列中,等主线程的任务执行完成以后,再回过头执行消息队列中的异步任务,如果异步任务中仍然有异步任务,会继续放入消息队列,以此类推,便形成了一个事件循环。
GET和POST的区别
- GET传输大小2K-8K,POST无限制
- 都不安全,GET通过url明文传输,POST通过body传输
- 浏览器会记录GET请求,不会记录POST
- GET对浏览器后退无影响,POST会再次提交
- 浏览器收藏:GET可以,POST不可以
- GET可缓存,POST不会
- GET用的url编码,POST支持多种编码
- GET产生一个TCP数据包,POST产生2个TCP数据包
- GET主要是拉取数据,POST主要是提交数据
防抖和节流
两者目的都是希望一段时间内不要重复请求。
应用场景:搜索,滚动。
区别:防抖是规定时间内只触发一次,再次调用时间重新计算。节流是在固定时间内只触发一次。
数组去重
- ES6 set去重
- Object key去重
- 两层循环遍历生成新的不重的数组
- indexOf()
- sort()排序后依次对比
数组排序
sort()排序
冒泡排序
选择排序
插入排序
常用设计模式
- 单例模式
- 工厂模式
- 观察者模式
- 适配器模式
for…of
es2015的语法
可以用来遍历数组、类数组、map/set/字符串等等。
- 数组遍历
1 | for (const number of [1, 2, 3]) {} |
- 类数组遍历
1 | for (const number of arguments) {} |
- 字符串遍历
1 | const msg = 'hello'; |
- Map遍历
1 | const map = new Map(); |
- Set遍历
1 | const names = new Set(['Tom', 'Jack', 'Lily']); |
前端常见攻击方式
- XSS
- CSRF
- sql注入
- html脚本注入
常见跨域方案
跨域源于浏览器的同源政策:必须同协议、同域名、同端口。
- JSONP(js调用)
- CORS(后台设置)
- Nginx反向代理(运维)
网站常用优化方案
思路:
减少请求次数
压缩资源大小
提高响应速度和加载速度
优化资源加载时机
优化加载方式
方法:
- 合并、压缩、混淆前端代码
- 服务器nginx开启gzip压缩
- 静态资源使用CDN
- 图标做base64处理以减小大小
- css放head,js放body中的最后面
- 设置缓存
- css和js的rel属性设置prefetch或preload可预加载资源
- 按需加载组件库
- 按需import和require
- 服务端渲染SSR,加快首屏渲染,利于SEO
- 页面使用骨架屏提高首页加载速度
- 尽量少使用jpeg和png,转而使用JPEG 2000, JPEG XR, WebP
- 图片懒加载