整理一些经常问的面试题
解构赋值
- ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被成为解构
- 解构赋值的左右结构必须一样,使用左边定义的值,能快速的取出数据对应的数据组,而且定义和赋值必须放到一起,不然的话就会报错,取不出来数据值,而且左边也必须是一个存在的js数据结构不然的话也会报错,解构赋值的主要作用还是快,快速的让我们在数据中拿到我们想要的数据。
async/await
asyns和await是一种同步的写法,但还是异步的操作,两个内容还是必须同时写才会生效不然的话还是不好使,但是await的话有一个不错的作用就是可以等到你的数据加载过来以后才会去运行下面的js内容,他必须接收一个promise对象,如果是接受数据的时候就可以直接用一句话来接收数据值,所有这个async await主要应用是在数据的接收,和异步问题的处理,主要是还是解决不同执行时机下的异步问题
promise是什么? 有哪些状态和参数? 如何使用?
他主要用于异步计算,可以将异步操作队列化,并按照期望的顺序执行,返回一个符合预期的结果
可以在对象之间传递和操作promise,帮助我们处理队列,
resolve作用是将promise对象的状态从未完成变成成功(也就是从pending变为resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject的作用是讲promise对象的状态从未完成变为失败(也就是冲pending变成rejected),在异步操作失败是调用,并将异步操作报出的错误,座位参数传递出去、
promise有三个状态:pending初始状态,fulfilled【实现】操作成功,reject【被否决】操作失败
当promise状态发生改变后就会触发then()里的响应函数处理后续步骤;当promise状态发送改变后就不会在变,promise对象改变状态只有两种可能,从pending变成fufilled或者从pending变成rejected。这两种情况只要发生,状态就凝固了,不会在变了
数据类型判断
- typeof 判断基本数据类型没有问题,但是如果是引用数据类型的话typeof是判断不出来的
- instanceof 只能判断到当前对象来自哪一个类
- constructor 几乎可以判断所有的基本数据类型和引用数据类型 但是如果声明一个构造函数且把他的原型指向array的原型的话 constructor也无法判断了
- 最好的解决方案就是用Object.prototype.toString.call()
对 SPA 单页面的理解,它的优缺点分别是什么?
SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载
-
优点:
用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
基于上面一点,SPA 相对对服务器压力小;
前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
-
缺点:
初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
说说对于 SSR了解?有没有使用过?
- Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
即:SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。 - 优点:
更好的 SEO: 因为 SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容,所以在 SPA 中是抓取不到页面通过 Ajax 获取到的内容;而 SSR 是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
更快的内容到达时间(首屏加载更快): SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间; - 缺点:
更多的开发条件限制: 例如服务端渲染只支持 beforCreate 和 created 两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序 SPA 不同,服务端渲染应用程序,需要处于 Node.js server 运行环境;
更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源。因此如果你预料在高流量环境下使用,请准备相应的服务器负载,并明智地采用缓存策略。
服务端渲染 SSR or 预渲染
- 服务端渲染是指 Vue 在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的 html 片段直接返回给客户端这个过程就叫做服务端渲染。
- **服务端渲染的优点:**见上一条SSR优点
- **服务端渲染的缺点:**见上一条SSR缺点
- 如果你的项目的 SEO 和 首屏渲染是评价项目的关键指标,那么你的项目就需要服务端渲染来帮助你实现最佳的初始加载性能和 SEO。如果你的 Vue 项目只需改善少数营销页面(例如 /products, /about, /contact 等)的 SEO,那么你可能需要预渲染,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点,具体你可以使用 prerender-spa-plugin 就可以轻松地添加预渲染 。
解释型语言的特性有什么?
解释性语言和编译性语言的定义:
计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。
解释性语言的定义:
解释性语言的程序不需要编译,在运行程序的时候才翻译,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就需要逐行翻译一次,效率比较低。
现代解释性语言通常把源程序编译成中间代码,然后用解释器把中间代码一条条翻译成目标机器代码,一条条执行。
编译性语言的定义:
编译性语言写的程序在被执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。
非独立:JavaScript语言依赖执行环境,对于客户端来说是浏览器,对于服务端来说是node。
效率低:执行前不需要编译,执行时才编译,因此效率低。
javascript中实现跨域的方式总结
- 第一种方式:jsonp请求;jsonp的原理是利用
<script>
标签的跨域特性,可以不受限制地从其他域中加载资源,类似的标签还有<img>
. - 第二种方式:document.domain;这种方式用在主域名相同子域名不同的跨域访问中
- 第三种方式:window.name;window的name属性有个特征:在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
- 第四种方式:window.postMessage;window.postMessages是html5中实现跨域访问的一种新方式,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源。
- 第五种方式:CORS;CORS背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是应该失败。
- 第六种方式:Web Sockets;web sockets原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。
javascript 模块化
commonjs是用在服务器端的,同步的,如nodejs
amd, cmd是用在浏览器端的,异步的,如requirejs和seajs
-
CommonJs 是服务器端模块的规范,Node.js采用了这个规范。
根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取
一个文件并执行,最后返回文件内部的exports对象。
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD 解决方案。
-
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。
适用AMD规范适用define方法定义模块。
-
CMD是SeaJS 在推广过程中对模块定义的规范化产出
CMD和AMD的区别有以下几点:
1.对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
2.CMD推崇依赖就近,AMD推崇依赖前置。虽然 AMD也支持CMD写法,但依赖前置是官方文档的默认模块定义写法。
3.AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的 require,提供 seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。
哪些表达式的值为0?
-
(()=>{}).length
-
1 & 2
-
+[]
-
[1,2,-3].reduce((a, b) => a - b, 0)
- (()=>{}).length; 获取方法形参个数,形参为0
- 1=0001 2=0010 按位与运算,同为1才为1,否则返回0
- +[] 隐式类型转换,因为[]是对象,所以toPrimitive->valueOf->toString为’’,结果就是+’’===0
- reduce对数组中的每个元素执行一个reducer函数(升序执行),将其结果汇总为单个返回值。a为累计器累计回调的返回值,b为数组的每一项元素,传入初始值0->0-(1)->(-1)-2->(-3)-(-3)->0
哪个结果,返回的是false
-
[] == true
-
!![]
-
NaN == NaN
-
null == undefined
第一个,两边都进行了隐式转换。true 会转为1 ,[ ] 会转为 0 ,最后是比较的是 0 == 1,所以结果是false。
[]转换成字符串为“”
[]转换成boolean为true;
[]转换成数字为0;
这样第二个中的[]即隐式转换为true
白屏时间first paint和可交互时间dom ready的关系是?
页面的性能指标详解:
白屏时间(first Paint Time)——用户从打开页面开始到页面开始有东西呈现为止
首屏时间——用户浏览器首屏内所有内容都呈现出来所花费的时间
用户可操作时间(dom Interactive)——用户可以进行正常的点击、输入等操作,默认可以统计domready时间,因为通常会在这时候绑定事件操作
总下载时间——页面所有资源都加载完成并呈现出来所花的时间,即页面 onload 的时间