JS、浏览器面试题
- 闭包是什么(★★★★★)
- GET和POST区别(★★★★★)
- 深拷贝和浅拷贝区别,如何实现(★★★★★)
- 箭头函数与普通函数的区别(★★★★★)
- cookie、sessionStorage、localStorage的区别?(★★★★★)
- cookie和session的区别(★★★★★)
- cookie的弊端(★)
- 什么是Promise、特点、使用场景?(★★★★★)
- Promise与Async/Await的区别?
- 如何解决跨域(★★★★★)
- 防抖和节流(★★★★★)
- 浏览器中输入url到网页显示,整个过程发生了什么(★)
- 浏览器如何渲染页面(★★)
- HTTP常见状态码(★★)
- git常用命令以及冲突解决?(★★)
- 对JSON的理解?(★)
- try...catch...使用场景(★)
- ES6 新增特性有哪些?(★)
- 清除浮动有哪几种方法?(★)
- var、let、const的区别?(★)
- 你有了解作用域吗?什么是作用域链(★)
- 原型和原型链是什么?(★)
- H5本地存储(★)
- 单页面与多页面的区别?(★)
- js继承的6种方式(★)
- 前端常见的设计模式?(★)
- 判断数据类型的方法有哪些?(★)
- 常见的浏览器内核有哪些?(★)
- 图片懒加载是怎么做的?(★)
- 使用 new 关键字做了什么?
- call、apply、bind区别
- 延迟(异步)加载JS有哪些方式?
- null和underfined的区别?
- 前端网页有几层构成?
- 谈谈你对web标准以及W3C的理解?
- axios 是什么,其特点和常用语法
- 浏览器兼容性问题?
- 说一下两个等号与三个等号的区别?
- this指向问题?
- 事件的故事
- JS哪些操作会造成内存泄漏?
闭包是什么(★★★★★)
闭包是指有权访问另一个函数作用域中的变量的函数。我的理解是闭包是一个函数里面嵌套了另一个函数,并且嵌套的函数可以访问到外部函数定义的变量。
- 作用:
可以读取函数内部的变量
将变量始终保持在内存中 - 优点:私有化变量,避免全局变量污染。
- 缺点:使用不当会造成内存泄漏(置为null可释放内存)。
- 应用场景:函数节流、防抖、封装功能和定时器等。
GET和POST区别(★★★★★)
- get的参数是暴露在url中的,并且是有长度限制的,而post的参数放在请求体中,且没有长度限制
- 相比于get请求,post请求更加安全
- get一般用于查询信息,而post用于提交数据
- get在浏览器回退不会再次请求,post会再次提交请求
- get请求会被浏览器主动缓存,post不会,要手动设置
- get请求参数会被完整保留在浏览器历史记录里,post中的参数不会
- get只有一种编码方式(url编码),而post支持多种编码方式
- get产生一个TCP数据包;post产生两个TCP数据包
深拷贝和浅拷贝区别,如何实现(★★★★★)
- 浅拷贝:
只是把对象的属性和属性值拷贝到另一个对象中,新旧对象还是共享同一块内存。方法有:Object.assign()、展开运算符、concat()、slice(). - 深拷贝:
深拷贝是把一个对象从内存中完整的拷贝出来,又在堆内存中开辟了新区域,用来存储新对象,并且修改新对象不会影响原对象。方法有 JSON.parse(JSON.stringify())、递归。
箭头函数与普通函数的区别(★★★★★)
- 箭头函数没有自己的this,它的this继承来的(外层第一个普通函数的this),且指向永远不会改变。
- 不可以当作构造函数使用,没有原型对象,也没有自己的 arguments 对象。
- call()、apply()、bind()方法不能改变this的指向。
cookie、sessionStorage、localStorage的区别?(★★★★★)
- 存储大小不同,cookie为4kb左右,sessionStorage 和 localStorage可以达到5MB
- 数据有效期不同,cookie可以设置过期时间,sessionStorage仅在当前窗口中有效,关闭页面或浏览器后被清除数据,而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
- 作用域不同,localstorage和cookie在同源窗口中数据是共享的,sessionStorage则不是。(不同浏览器不共享)
cookie和session的区别(★★★★★)
- 位置不一样。Cookie存储在客户端,Session存储在服务器
- 大小不一样。单个Cookie保存的数据不能超过4KB,Session的大小主要受服务器资源的限制。
- 存储类型不一样。session 可以存储多种数据类型,cookie 只能存储的是字符串类型
- 安全性不一样。Session比Cookie更具有安全性,因为数据存储在服务器端。
- 服务器压力不一样。服务器压力不同,Session占用服务器性能,Session过多,增加服务器压力
cookie的弊端(★)
- 有数量和大小的限制。每个域名下最多只能有20-50条cookie,每个cookie大小限制为4KB左右。
- 增加流量消耗,每次请求都需要带上cookie信息。
- 存在安全隐患,cookie使用明文传输,如果cookie被人拦截了,那人就可以取得所有的session信息。
什么是Promise、特点、使用场景?(★★★★★)
- Promise 是es6的新特性,异步编程的一种解决方案。
- Promise有三种状态:pending(等待状态)、fulfilled(成功状态)和 rejected(失败状态),有两种状态变化,分别是pending到fulfilled 和pending到rejected,同时状态变化是不可逆。
- Promise提供 then 方法和 catch 方法,then方法第一个参数接收resolved传来的数据,catch方法第一个参数是接收rejected传来的数据。
- 然后 then 方法返回一个新的Promise,因此可以通过链式调用then方法。
- 常用于封装api接口、文件读写等操作。
- Promise.all():将多个Promise封装成一个新的Promise,成功时按顺序返回的是一个结果数组,失败时,返回的是最先rejected状态的值。使用场景:需要发送多个请求并根据请求顺序返回数据的需求。
- Promise.race():就是多个Promise中,哪个状态先变为成功或者失败,就返回哪个Promise的值。使用场景:可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作。
Promise与Async/Await的区别?
- 语法不同。
Promise 的语法是 then/catch,而 async/await 的语法是 async/await关键字。
Promise 的 then 方法返回一个新的 Promise 对象,而 async/await 是直接使用 await 关键字等待异步结果。 - 错误处理不同
Promise 使用 catch 处理异常,而 async/await 使用 try/catch 处理异常。
使用 async/await 可以让代码更加清晰明了,异常处理也更加方便。 - 并发处理能力不同
Promise 可以并行执行多个异步操作,而 async/await 只能串行执行异步操作。
使用 Promise 可以提高代码的性能,但是在处理多个异步操作时需要注意控制并发数。
如何解决跨域(★★★★★)
只要协议、域名和端口号三个中有一个不一样就算跨域。
- jsonp跨域
利用 script 标签没有跨域限制,通过 script 标签的src属性,发送带有callback参数的get请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据 - CORS(后台设置响应头)
- Nginx反向代理
- nodejs中间件代理跨域
- postMessage通信跨域
- WebSocket协议跨域
防抖和节流(★★★★★)
防抖
- n 秒后再执行事件,如果在 n 秒内重新触发,则会重新计时。
- 实现:设置一个定时器,再次触发事件先清除定时器再设置。
- 场景:搜索框输入显示、手机号输入检测、窗口大小计算。
节流
- n秒内只执行一次,如果在 n 秒内重新触发,只有一次生效。
- 实现:设置一个状态锁,默认为开锁,点击时候判断状态为开锁才可以请求,同时对状态上锁,只有请求结束后才开锁。
- 场景:懒加载、滚动加载、高频点击提交。
浏览器中输入url到网页显示,整个过程发生了什么(★)
- 浏览器会将 URL 交给 DNS 进行域名解析
- 然后建立tcp连接(三次挥手)
- 发起htttp请求
- 服务器端处理相关请求,返回相应的结果
- 关闭tcp连接
- 然后浏览器对HTML进行解析,并请求代码中的资源
- 最后浏览器对页面进行渲染,呈现给用户
浏览器如何渲染页面(★★)
- 渲染引擎首先解析HTML文档,生成DOM树。
- 解析CSS样式,生成CSSOM树(CSS规则树)。
- 将DOM树与CSSOM树合并,构建渲染树。
- 进行回流,根据渲染树计算得到节点的几何信息。
- 进行重绘,根据计算好的信息绘制整个页面。
HTTP常见状态码(★★)
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
- 1开头的状态码:指示信息–表示请求已接收,继续处理
- 2开头的状态码:成功–表示请求已被成功接收、理解、接受(200:表示请求成功)
- 3开头的状态码:重定向–要完成请求必须进行更进一步的操作
301:永久重定向(请求的网页已永久移动到新位置);
302:临时重定向 - 4开头的状态码:客户端错误–请求有语法错误或请求无法实现
401:未授权;
403:服务器拒绝请求;
404:请求页面不存在; - 5开头的状态码:服务器端错误–服务器未能实现合法的请求
500:表示服务器错误;
503:服务器维护
git常用命令以及冲突解决?(★★)
git add # 将工作区的修改提交到暂存区
git commit # 将暂存区的修改提交到当前分支
git push # 将本地代码更新到远程分支上
git branch # 查看当前分支
git checkout # 切换分支
git status # 查看当前仓库的状态
git merge # 合并分支
git pull # 从远程更新代码
git log # 查看提交历史
git reset # 回退到某一个版本
git stash # 保存某次修改
git reflog # 查看历史命令
git diff # 查看修改
git revert # 回退某个修改
对JSON的理解?(★)
- JSON是一种轻量级的用于存储和交换数据的格式,是独立于任何编程语言的数据格式。
- JSON.stringify():将javascript值转换为JSON字符串。
- JSON.parse():将JSON字符串转换为javascript对象。
try…catch…使用场景(★)
- 一般用于可控的错误,而不是未知的错误
- 适用于浏览器兼容问题、判断代码非法性等场景
- 只能捕捉同步的异常,异步的异常无法捕捉。
- 也可以用于终止forEach循环,使用 throw new Error
ES6 新增特性有哪些?(★)
块级作用域(let,const)
箭头函数
Promise 对象
解构赋值
模块化(import/export)
Symbol基本数据类型
模板字符串
Proxy 构造函数,用来生成 Proxy 实例
class类
生成器(Generator)和遍历器(Iterator)
Set 和 Map 数据结构
数组新增方法,如 map()、filter()、reduce()、some()、every()等
清除浮动有哪几种方法?(★)
- 直接设置父元素高度。简单代码少 ,但只适合高度固定的布局。
- 给父元素添加overflow:hidden样式。 (超出盒子部分会被隐藏,不推荐使用)
- 额外标签法:在浮动元素的后面加一个空标签,再给这个标签加上clear:both 样式。(让父级 div 能自动获取到高度 ,如果页面浮动布局多,就要增加很多空 div,让人感觉很不好 )
- :after伪元素法(clearfix为父元素类名):
.clearfix:after {
content:"";
display:block;
visibility:hidden;
height:0;
clear:both;
}
.clearfix {
zoom:1
}
- :after和:before双伪元素法:
.clearfix:after,.clearfix:before {
content:"";
display:block;
clear:both;
}
.clearfix {
zoom:1
}
var、let、const的区别?(★)
- 作用域范围不同,var是函数作用域,其他两个是块级作用域。
- var声明的变量可进行变量提升,let和const则不行。
- var允许重复声明同一变量,其他两个不允许。
- const声明的变量必须进行初始化,且不能修改,var和let则是可以重新赋值。
你有了解作用域吗?什么是作用域链(★)
- 作用域就是变量和函数起作用的范围。
- 查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称为作用域链。
原型和原型链是什么?(★)
- 原型:对象中有一个固有的__proto__属性,该属性指向该对象的prototype原型属性。
- 原型链:当访问一个对象的某个属性时,如果对象内部不存在这个属性,那么它就会去原型对象里面找,而这个原型对象又有自己的原型,就会这样一直找下去,也就是原型链。
H5本地存储(★)
H5本地存储有localStorage和sessonStorage和本地数据库。localStorage和sessonStorage都有四个方法:
- localStorage.settem 存储数据信息到本地
- localStorage.getItem 读取本地存储的信息
- localStorage.removeItem 删除本地存储的信息
- localStorage.clear 清空所以存储的信息
单页面与多页面的区别?(★)
单页面(SPA) | 多页面(MPA) |
---|---|
结构不同:一个主页面 + 多个模块组件 | 多个完整页面 |
体验不同:页面切换速度快,用户体验较好 | 页面切换速度慢 |
刷新方式不同:局部刷新 | 整页刷新 |
路由模式不同:hash模式或者history模式 | 普通链接跳转 |
加载资源文件不同:组件公用资源只需加载一次 | 每个页面都要自己加载公用资源 |
数据传递不同:借助vuex容易 | 依赖 url、cookie 、localStorage等传参 |
适用场景不同: 不利于SEO | 适用于对SEO要求较高的应用 |
开发成本不同:较高,需要专业的框架 | 较低,但重复代码多 |
维护成本不同:相对容易 | 相对复杂 |
js继承的6种方式(★)
- 原型链继承
核心:将父类的实例作为子类的原型 - 构造函数继承
- 组合继承
- 原型式继承
- 寄生式继承
- 寄生组合式继承
前端常见的设计模式?(★)
- 单例模式:指的是创建的总是同一个实例。也就是使用类创建的实例始终是相同的。
- 观察者模式:观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得他们能够自动更新自己。
- 策略模式:将一系列算法封装起来,并使它们相互之间可以替换。
- 代理模式:为对象提供一个代理,用来控制对这个对象的访问。
- 工厂模式
判断数据类型的方法有哪些?(★)
- typeof 用来判断基本数据类型,不能判断复杂数据类型,返回的是字符串。
- instanceof 用于判断一个变量是否属于某个对象的实例,返回的是布尔值。
- Object.prototype.toString.call 基本可以判断所有数据类型,返回的是 [ object, [[class]]] 格式的字符串。
- constructor 不能判断undefined和null,返回的是布尔值。
常见的浏览器内核有哪些?(★)
- Trident内核:IE浏览器。
- Gecko内核:Firefox浏览器。
- Webkit内核:Safari浏览器。
- Presto内核:Opera浏览器。
- Blink内核:Chrome浏览器。
图片懒加载是怎么做的?(★)
- 懒加载就是将不关键的资源延后加载。
- 懒加载的原理就是只加载自定义区域(通常是可视区域,但也可以是即将进入可视区域)内需要加载的东西。对于图片来说,先设置图片标签的 src属性为一张占位图,将真实的图片资源放入一个自定义属性中,当进入自定义区域时,就将自定义属性替换为 src属性,这样图片就会去下载资源,实现了图片懒加载。
- 懒加载不仅可以用于图片,也可以使用在别的资源上。比如进入可视区域才开始播放视频等等。
使用 new 关键字做了什么?
function Person() {
this.name = '小明'
}
- 创建了一个空对象
let obj = new Object();
- 使空对象的隐式原型指向构造函数的显示原型
obj._proto_ = Person.prototype;
- 修改构造函数this的指向,使其指向新建的空对象
let result = Person.call()
- 将这个对象返回出去
return this
call、apply、bind区别
1.相同点
- 都是用来改变this指向
- 接收的第一个参数都是this要指向的对象
- 都可以利用后续参数传参
2.不同点
- call和bind传参相同,多个参数依次传入
- apply只有两个参数,第二个参数为数组
- call和apply都是改变this指向后直接调用,而bind不会,而是返回一个修改this后的函数
延迟(异步)加载JS有哪些方式?
- 延迟加载: async、 defer 例如:
<script defer type= "text/javascript" src='script.js'><script>
- defer :等html全部解析完成, 才会执行js代码,顺次执行js脚本。
- async : async是和html解析同步的(一起的), 不是顺次执行js脚本(谁先加载完谁先执行)。
null和underfined的区别?
- null表示定义了一个空对象,主要用于赋值给一些可能返回对象的变量,作为初始化(转为数值时为0)。
- underfined表示变量声明了还没定义,就会返回underfined(转为数值时为NaN)。
前端网页有几层构成?
- 结构层:由HTML之类的标记语言负责创建,即是标签。
- 表示层:由CSS去负责如何展示。
- 行为层:由JS去负责网页动作行为反应。
谈谈你对web标准以及W3C的理解?
web标准主要分为结构、表现、行为3部分
- 结构:指我们平时在body里面写的标签,主要是由HTML标签组成
- 表现:指更加丰富HTML标签样式,主要由CSS样式组成
- 行为:指页面和用户的交互,主要由JS部分组成
W3C对web标准提出了规范化的要求,即代码规范。
- 对结构的要求
1、标签字母要小写
2、标签要闭合
3、标签不允许随意嵌套 - 对表现和行为的要求
建议使用外链CSS和js脚本,实现结构与表现分离、结构与行为分离,能提高页面的渲染效率,更快地显示网页内容
axios 是什么,其特点和常用语法
- Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求
- 特点:
基于 promise 的异步 ajax 请求库,支持promise所有的API 。
浏览器端/node端都可以使用,浏览器中创建XMLHttpRequests 。
支持请求/响应拦截器 。
支持请求取消。
可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据 。
批量发送多个请求 安全性更高,客户端支持防御XSRF,就是让你的每个请求都带一个从cookie中拿到的key,根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
浏览器兼容性问题?
- 不同浏览器的标签默认外边距margin和内边距padding不同
解决方案:使用CSS通配符*,设置内外补丁为0,*{ margin: 0; padding: 0;} - 图片默认有间距
问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,通配符清除间距也不起作用。
解决方案:使用float属性为img布局 - 上下margin的重叠问题
描述:给上边元素设置了margin-bottom,给下边元素设置了margin-top,浏览器只会识别较大值;
解决方案:margin-top和margin-bottom中选择一个,只设置其中一个值;
说一下两个等号与三个等号的区别?
- ==是非严格意义上的相等,如果两边的类型不一致,则会进行强制类型转化后再进行比较,值相等就相等
- ===是严格意义上的相等,会比较两边的数据类型和值大小,不会做强制类型准换,值和引用地址都相等才相等
this指向问题?
- 全局作用域下或者普通函数中的this指向的是window
- 作为对象方法调用时,指向调用的对象
- 事件函数中的this指向事件源
- 构造函数中的this指向创建出来的对象
事件的故事
- 事件类型分两种:事件捕获、事件冒泡。
- 事件捕获:由外往内,从事件发生的顶点开始,逐级往下查找,一直到目标元素。
- 事件冒泡:就是由内往外,从具体的目标节点元素触发,逐级向上传递,直到根节点。
- 事件委托,又名事件代理。事件委托就是利用事件冒泡,就是把子元素的事件都绑定到父元素上。如果子元素阻止了事件冒泡,那么委托也就没法实现了
JS哪些操作会造成内存泄漏?
- 全局变量使用不当
- 没有清除定时器
- 过多使用闭包
- dom清空时还存在引用