一.js的基本类型和引用类型
答:JS 中有七种内置类型null,undefined,boolean,number,string,symbol,object。又分为两大类型,前六种为基础类型,object为引用类型(Function,Array,Data,RegExp都属于Object引用类型,)。其中最重要的区别就是基础类型的值直接存储在栈内存中,而引用类型的值保存在堆内存中,只是一个指针保存在栈内存中
更细致的区别参考:https://segmentfault.com/a/1190000022471161
二.js数组的浅拷贝与深拷贝的区别
答:浅拷贝就是再声明一个数组,直接让此拷贝数组指向原数组的内存地址中,拷贝的数组与原数组公用一个内存地址,所以如果改变拷贝数组的值,原数组也会改变。
实现方法:简单赋值
深拷贝就是真真正正的复制原数组到新的内存空间中,拷贝完成后互不干扰
实现方法:遍历原数组赋值到新数组(遍历),使用slice()方法能够生成新数组(注意,得自己会写深拷贝,超高频笔试题)
三.如何判断一个类型是数组
答:使用isArray()方法
var a = [1,2,3];
console.log(typeof a); //返回“object”
console.log(Array.isArray(a)); //true
四.jsonp的优缺点
优点:
1. 不受到同源策略的限制。
2. 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
缺点:
1. 只支持GET请求而不支持其它类型的HTTP请求。
2. 它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
3. jsonp在调用失败的时候不会返回各种HTTP状态码。
4. 安全性问题。假如提供jsonp的服务存在页面注入的漏洞,就有可能会导致所有调用这个jsonp的网站都会存在漏洞。所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
五.CORS的优缺点
优点:
1.相对与jsonp更安全更方便简洁
2.功能更强大,支持所有类型的请求
缺点:
1.ie10以下不支持CORS
2.由于CORS是W3C中一项较“新”的方案,以至于各大网页解析引擎还没有对其进行严格规格的实现,所以不同引擎下可能会有一些不一致。
六.call, apply和bind方法的区别
答:call、apply 和 bind 的作用都是改变 this 的指向,其中 call 和 apply 的区别在于它们传参的方式不同——call可以传多个形参,而apply只能传一个数组形参。而bind和call、apply的区别在于bind不会立即调用,而是返回一个函数对象,因此开发中一般用bind比较多
教学视频:https://www.bilibili.com/video/BV1Ug411F7fZ?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click
七.从输入 URL 到页面展示浏览器里发生了什么?
答:
1.输入IP地址后开始逐步找ip地址,本机找不到到DNS服务器找
2.一系列网络沟通后拿到html文件浏览开始渲染
3.请求嵌入html文件中的资源
4.展示完整页面
八.什么是服务器渲染什么是前端渲染
答:
服务端渲染:
服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示。比如:jsp页面
好处:前端耗时少,即减少了首屏时间,模板统一在后端。前端(相对)省事,不占用客户端运算资源(解析模板)
坏处:占用服务器资源。
前端渲染:
浏览器中显示的网页中的大部分内容,都是由前端写的 js 代码在浏览器中执行,最终渲染出来的网页。
也可以怎么说:后端返回JSON数据,前端利用预先写的html模板,循环读取JSON数据,拼接字符串,并插入页面。
好处:网络传输数据量小。不占用服务端运算资源(解析模板),模板在前端(很有可能仅部分在前端),改结构变交互都前端自己来了,改完自己调就行。
坏处:前端耗时较多,对前端工作人员水平要求相对较高。前端代码较多,因为部分以前在后台处理的交互逻辑交给了前端处理。占用少部分客户端运算资源用于解析模板.
九.你是如何理解html语义化标签的
答:语义化标签除了方便程序员阅读代码,提高程序员维护代码的成本,同时适当的使用语义化标签还能提升页面的权重,使页面更容易被浏览器爬虫抓取到
十.HashRouter和HistoryRouter的区别
答:
1.history和hash都是利用浏览器的两种特性实现前端路由,history是利用浏览历史记录栈的API实现,hash是监听location对象hash值变化事件来实现
2.history的url没有’#'号,hash反之
3.相同的url,history会触发添加到浏览器历史记录栈中,hash不会触发
4.HashRouter的原理:通过window.onhashchange方法获取新URL中hash值,再做进一步处理
HistoryRouter的原理:通过history.pushState 使用它做页面跳转不会触发页面刷新,使用window.onpopstate 监听浏览器的前进和后退,再做其他处理
加分回答
需要兼容低版本的浏览器时,建议使用hash模式。
需要添加任意类型数据到记录时,可以使用history模式。
十一.浏览器同源策略
答:
只有域名,协议,端口都相同时,才算同源
来自MDN:
如果不是同源的站点,将不能进行如下操作 :
Cookie、LocalStorage 和 IndexDB 无法读写
DOM 和 Js对象无法获得
AJAX请求不能发送
如果没有同源策略其实是很可怕的事情,比如用户登录了一个恶意网站,如果没有同源策略,这个网站将可以获取到客户存在浏览器的所有cookie,然后再给冒充用户给某些网站发送ajax请求
十二.http状态码
答:
1xx : 接受的请求正在被处理
2xx : 请求正常处理完毕
3xx : 需要进行附加操作以完成请求
4xx : 服务器无法处理请求
5xx : 服务器处理请求出错
十三. 重排和重绘,以及优化重排重绘的方案
答:
重排:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的规模尺寸、布局或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。完成重排后,浏览器重新绘制受影响的部分到屏幕上,该过程为重绘。
重绘:当渲染树中一些元素需要更新属性,这些属性只影响外观、风格,不影响布局,比如background-color
优化策略:
1.浏览器会维护一个队列,把所有引起重排、重绘的操作放入这个队列,等队列中的操作到了一定数量或时间间隔,浏览器就会flush队列,进行一个批处理。这样让多次的重排重绘变成一次。
2.将多次改变样式属性的操作合并为一次操作:将对元素的多次修改想办法合并为一次
十四. 防抖和节流及应用场景
答:
防抖就像英雄联盟或者王者荣耀的回城,要读条,一旦被打断就要重新读条,要完整读完条才能回去。
应用场景:鼠标滑动事件,输入框搜索功能
节流就是比如用户一直点左键,那么在用户一直点左键这个时间段里我们规定事件按一定时间频率来触发:间隔一秒触发一次
十五. http1.0,1.1和2.0的区别
先看各协议访问同样大小的网站的各个差异
可以看到http2.0对速度的提示非常大,在发送530个http请求的时候只需要进行一次tcp链接,而http1.0则每次都需要进行一次tcp链接。热知识:浏览器其实会同时建立多个tcp连接去请求同一个资源,这样可以优化资源的请求速度,但就谷歌浏览器来说,只能同时允许6个tcp连接同时请求同一个资源,不能太多是因为这样会造成服务器的压力太大
答:
http1.0每次连接都需要先进行tcp连接,到http1.1时提出了keep-alive,在客户端和服务端都不提出连接中断时便会一直保持连接,达到复用http连接的效果,减少了tcp连接。那么http2.0则是通过了压缩头部的方法来优化请求的,会将要请求的资源放在同一个头部里,说得更少,做得一样多(所以我们看见http2.0的网络传输量少,就是因为被压缩了。而http1.1网络传输量多了就是因为头部多了keep-alive这个信息,所以网络传输量会反而多了)。http2.0做的远不止于此,还有一个二进制分帧层的优化技术,解决了http1.0,1.1里存在的问题,对头阻塞:比如浏览器同时请求了图片1和图片2,就算图片2较小,先返回了,但浏览器也得等图片1返回了,处理了图片1再处理图片2。使用了这个所谓的二进制分帧层的优化技术之后呢就能先处理图片2再处理图片1也是没有问题的啦
十六. 对虚拟DOM的理解
答:
这个问题比较常见的回答思路是:“DOM 操作是很慢的,而 JS 却可以很快,直接操作 DOM 可能会导致频繁的回流与重绘,JS 不存在这些问题。因此虚拟 DOM 比原生 DOM 更快”,但我对这句话一直持疑不定,如果js操作完虚拟DOM之后虚拟DOM再更新到真实DOM,那虚拟DOM的作用似乎不大啊。 上网看了几篇文章后,才真正明白了虚拟DOM的作用:
在没有虚拟DOM的情况下,如果对html模板进行了修改,那么会将修改后的生成的DOM替换旧的DOM。这无疑是对性能的很大消耗。在有了虚拟DOM之后,对html模板进行了修改,不会直接对真实DOM进行操作,而是先生成虚拟DOM,再与先前存在的虚拟DOM进行diff算法,看看有什么不同,把不同替换掉,再将虚拟DOM渲染成真实DOM,虚拟DOM就是这么回事:只是加了一些特别的步骤来避免了整棵 DOM 树变更
十七. 进程和线程
答:
线程是进程的一个执行单位,线程共享本进程的地址空间,而进程之间是独立的地址空间
十八. 为什么js设计成单线程的
答:
因为js是设计来操作DOM的,还会操作许多网络请求的操作,如果设计成多线程就会需要进行很多的控制操作
十九 . v8垃圾回收
答:
经典的垃圾回收算法有:标记清理、引用计数
标记清理:先将所有变量标记,进行垃圾回收就从根对象开始遍历,有被引用的变量就去掉标记,然后删除掉有标记的变量之后再将所以变量打上标记,这个算法有个缺点就是会产生内存碎片
引用计数:其思路是对每个变量记录它被引用的次数,通过最后对次数的判断(引用数为0)来决定是否保留。但弊端也很明显,如果存在闭包,那此变量就永远都不会被销毁了。所以用得也比较少
新老生代回收算法:
将堆内存分为新生代和老生代两个区域,新生代又分为from和to两个区域,每次垃圾回收时会对新生代区域进行操作,将活跃的的从from复制到to,然后回收from区域的变量,如果变量经过多次操作后仍然存活就会被放到老生代。老生代区域的垃圾回收就使用上面所说的标记清理
二十. for in 与 for of 的区别
答:
for in遍历的得键,而for of遍历得值
for in总是得到对象的key或数组、字符串的下标
for of总是得到对象的value或数组、字符串的值
但for in会遍历原型链中所有的可枚举属性,要慎用
二十一. call apply bind 的区别
答:call和apply的第一个参数都是将要绑定到的对象,而传递参数时,call使用第二第三第四第五参数,apply则是在第二个参数中将参数以数组的方式传递。bind则是只有将要绑定的对象一个参数,不过不是立即执行,而是返回一个函数,这个函数就是已经完成绑定的函数
二十二. 什么是函数柯里化
答:概括柯里化:把接收多参的函数转化成可以逐个调用单个参数并返回接收剩下参数的函数
比如一个函数是func(a,b,c)进入柯里化函数转化一下 _.curry(func)就会变成func(a)(b)(*c),可以单独执行func(a)或者是func(b)或者是func(*c)。
至于用法嘛,在实际开发中没有使用过,不过学习vue源码时知道,vue在将DOM转化为抽象语法树时就使用了函数柯里化来优化性能
陆续更新中。。。