ES6面试、复习干货知识点汇总(全)

原创 tiansuiziswj 教程 es6 129阅读 2018-12-10 13:55:27 举报

近期在复习ES6,针对ES6新的知识点,以问答形式整理一个全面知识和问题汇总。(全干货,适合对ES6有一定理解的同学复习,以及ES6面试。)

一、问:ES6是什么,为什么要学习它,不学习ES6会怎么样?

答: ES6是新一代的JS语言标准,对分JS语言核心内容做了升级优化,规范了JS使用标准,新增了JS原生方法,使得JS使用更加规范,更加优雅,更适合大型应用的开发。学习ES6是成为专业前端正规军的必经之路。不学习ES6也可以写代码打鬼子,但是最多只能当个游击队长。

二、问:ES5、ES6和ES2015有什么区别?

答: ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015、ES2016、ES2017、ES2018等。现阶段在绝大部分场景下,ES2015默认等同ES6。ES5泛指上一代语言标准。ES2015可以理解为ES5和ES6的时间分界线。

三、问:babel是什么,有什么作用?

答:babel是一个 ES6 转码器,可以将 ES6 代码转为 ES5 代码,以便兼容那些还没支持ES6的平台。

四、问:let有什么用,有了var为什么还要用let?

答: 在ES6之前,声明变量只能用var,var方式声明变量其实是很不合理的,准确的说,是因为ES5里面没有块级作用域是很不合理的,甚至可以说是一个语言层面的bug(这也是很多c++、java开发人员看不懂,也瞧不起JS语言的劣势之一)。没有块级作用域回来带很多难以理解的问题,比如for循环var变量泄露,变量覆盖等问题。let 声明的变量<font color="#3CB371">拥有自己的块级作用域</font>,且修复了var声明变量带来的<font color="#3CB371">变量提升问题</font>。

五、问:举一些ES6对String字符串类型做的常用升级优化?

答:

1、优化部分:

ES6新增了字符串模板,在拼接大段字符串时,用反斜杠(`)取代以往的字符串相加的形式,<font color="#3CB371">能保留所有空格和换行</font>,使得字符串拼接看起来更加直观,更加优雅。

2、升级部分:

ES6在String原型上新增了includes()方法,用于取代传统的只能用indexOf查找包含字符的方法(indexOf返回-1表示没查到不如includes方法返回false更明确,语义更清晰), 此外还新增了<font color="#3CB371">startsWith(), endsWith(), padStart(),padEnd(),repeat()</font>等方法,可方便的用于查找,补全字符串。

六、问:举一些ES6对Array数组类型做的常用升级优化?

答:

1、优化部分:

a. 数组解构赋值。ES6可以直接以<font color="#3CB371">let [a,b,c] = [1,2,3]</font>形式进行变量赋值,在声明较多变量时,不用再写很多let(var),且映射关系清晰,且支持赋默认值。

b. 扩展运算符。ES6新增的扩展运算符<font color="#FF0000">(...)(重要)</font>,可以轻松的实现数组和松散序列的相互转化,可以取代arguments对象和apply方法,轻松获取未知参数个数情况下的参数集合。<font color="#DAA520">(尤其是在ES5中,arguments并不是一个真正的数组,而是一个类数组的对象,但是扩展运算符的逆运算却可以返回一个真正的数组)</font>。扩展运算符还可以轻松方便的实现数组的复制和解构赋值(let a = [2,3,4]; let b = [...a])。

2、升级部分:

ES6在Array原型上新增了find()方法,用于取代传统的只能用indexOf查找包含数组项目的方法,且<font color="#3CB371">修复了indexOf查找不到NaN的bug([NaN].indexOf(NaN) === -1)</font>.此外还新增了<font color="#3CB371">copyWithin(), includes(), fill(),flat()</font>等方法,可方便的用于字符串的查找,补全,转换等。

七、问:举一些ES6对Number数字类型做的常用升级优化?

答:

1、优化部分:

ES6在Number原型上新增了isFinite(), isNaN()方法,用来取代传统的全局isFinite(), isNaN()方法检测数值是否有限、是否是NaN。ES5的isFinite(), isNaN()方法都会先将非数值类型的参数转化为Number类型再做判断,这其实是不合理的,最造成isNaN('NaN') === true的奇怪行为--'NaN'是一个字符串,但是isNaN却说这就是NaN。而Number.isFinite()和Number.isNaN()则不会有此类问题(Number.isNaN('NaN') === false)。(isFinite()同上)

2、升级部分:

ES6在Math对象上新增了Math.cbrt(),trunc(),hypot()等等较多的科学计数法运算方法,可以更加全面的进行立方根、求和立方根等等科学计算。

八、问:举一些ES6对Object类型做的常用升级优化?<font color="#FF0000">(重要)</font>

答:

1、优化部分:

a. 对象属性变量式声明。ES6可以直接以<font color="#3CB371">变量形式声明对象属性或者方法</font>,。比传统的键值对形式声明更加简洁,更加方便,语义更加清晰。

尤其在<font color="#3CB371">对象解构赋值(见优化部分b.)或者模块输出变量</font>时,这种写法的好处体现的最为明显:

可以看到属性变量式声明属性看起来更加简洁明了。方法也可以采用简洁写法:

b. 对象的解构赋值。 ES6对象也可以像数组解构赋值那样,进行变量的解构赋值:

c. 对象的扩展运算符(...)。 ES6对象的扩展运算符和数组扩展运算符用法本质上差别不大,毕竟数组也就是特殊的对象。对象的扩展运算符一个最最常用也最好用的用处就在于可以<font color="#3CB371">轻松的取出一个目标对象内部全部或者部分的可遍历属性,从而进行对象的合并和分解</font>。

d. <font color="#FF0000">super</font> 关键字。ES6在Class类里新增了类似this的关键字super。同this总是指向当前函数所在的对象不同,super关键字总是<font color="#DAA520">指向当前函数所在对象的原型对象</font>。

2、升级部分:

a. ES6在Object原型上新增了is()方法,做两个目标对象的相等比较,用来完善'==='方法。'==='方法中NaN === NaN //false其实是不合理的,Object.is修复了这个小bug。(Object.is(NaN, NaN) // true)

b. ES6在Object原型上新增了assign()方法,用于对象新增属性或者多个对象合并。

注意: <font color="#DAA520">assign合并的对象target只能合并source1、source2中的自身属性,并不会合并source1、source2中的继承属性,也不会合并不可枚举的属性</font>,<font color="#FF0000">且无法正确复制get和set属性(会直接执行get/set函数,取return的值)</font>。

c. ES6在Object原型上新增了getOwnPropertyDescriptors()方法,此方法增强了ES5中getOwnPropertyDescriptor()方法,可以获取指定对象所有<font color="#DAA520">自身</font>属性的描述对象。结合defineProperties()方法,可以完美复制对象,包括复制get和set属性。

d. ES6在Object原型上新增了getPrototypeOf()和setPrototypeOf()方法,用来获取或设置当前对象的prototype对象。这个方法存在的意义在于,ES5中获取设置prototype对像是通过proto属性来实现的,然而proto属性并不是ES规范中的明文规定的属性,只是浏览器各大产商“私自”加上去的属性,只不过因为适用范围广而被默认使用了,再非浏览器环境中并<font color="#DAA520">不一定就可以使用</font>,所以为了稳妥起见,获取或设置当前对象的prototype对象时,都应该采用ES6新增的标准用法。

d. ES6在Object原型上还新增了Object.keys(),Object.values(),Object.entries()方法,用来获取对象的所有键、所有值和所有键值对数组。

九、问:举一些ES6对Function函数类型做的常用升级优化?<font color="#FF0000">(重要)</font>

答:

1、优化部分:

a. 箭头函数<font color="#FF0000">(核心)</font>。箭头函数是ES6核心的升级项之一,箭头函数里没有自己的this,这改变了以往JS函数中最让人难以理解的this运行机制。主要优化点:

Ⅰ. &nbsp;&nbsp; <font color="#DAA520">箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象</font>。ES5函数里的this总是指向函数执行时所在的对象,这使得在很多情况下this的指向变得很难理解,尤其是非严格模式情况下,this有时候会指向全局对象,这甚至也可以归结为语言层面的bug之一。ES6的箭头函数优化了这一点,它的内部没有自己的this,这也就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己this的函数为止,并作为自己的this。

Ⅱ. &nbsp;&nbsp; 箭头函数不能用作构造函数,因为它没有自己的this,无法实例化。

Ⅲ. &nbsp;&nbsp;也是因为箭头函数没有自己的this,所以箭头函数 内也不存在arguments对象。(可以用扩展运算符代替)

b. 函数默认赋值。ES6之前,函数的形参是无法给默认值得,只能在函数内部通过变通方法实现。ES6以更简洁更明确的方式进行函数默认赋值。

2、升级部分:

ES6新增了双冒号运算符,用来取代以往的bind,call,和apply。

十、问:Symbol是什么,有什么作用?

答: Symbol是ES6引入的第七种原始数据类型,所有Symbol()生成的值都是独一无二的,可以<font color="#3CB371">从根本上解决对象属性太多导致属性名冲突覆盖的问题</font>。对象中Symbol()属性不能被for...in遍历,但是也不是私有属性。

十一、问:Set是什么,有什么作用?

答: Set是ES6引入的一种类似Array的新的数据结构,Set实例的成员类似于数组item成员,区别是Set实例的成员都是<font color="#3CB371">唯一,不重复的</font>。这个特性可以轻松地实现<font color="#3CB371">数组去重</font>。

十二、问:Map是什么,有什么作用?

答: Map是ES6引入的一种类似Object的新的数据结构,Map可以理解为是Object的超集,打破了以传统键值对形式定义对象,对象的key不再局限于字符串,<font color="#3CB371">也可以是Object</font>。可以更加全面的描述对象的属性。

十三、问:Proxy是什么,有什么作用?

答: Proxy是ES6新增的一个构造函数,可以理解为JS语言的一个代理,用来改变JS默认的一些语言行为,包括拦截默认的get/set等底层方法,使得JS的使用自由度更高,可以最大限度的满足开发者的需求。比如通过拦截对象的get/set方法,可以轻松地定制自己想要的key或者value。下面的例子可以看到,随便定义一个myOwnObj的key,都可以变成自己想要的函数。

十四、问:Reflect是什么,有什么作用?

答: Reflect是ES6引入的一个新的对象,他的主要作用有两点,一是将原生的一些零散分布在Object、Function或者全局函数里的方法(如apply、delete、get、set等等),统一整合到Reflect上,这样可以更加方便更加统一的管理一些原生API。其次就是因为Proxy可以改写默认的原生API,如果一旦原生API别改写可能就找不到了,所以Reflect也可以起到备份原生API的作用,使得即使原生API被改写了之后,也可以在被改写之后的API用上默认的API。

十五、问:Promise是什么,有什么作用?

答: Promise是ES6引入的一个新的对象,他的主要作用是用来解决JS异步机制里,回调机制产生的“回调地狱”。它并不是什么突破性的API,只是封装了异步回调形式,使得异步回调可以写的更加优雅,可读性更高,而且可以链式调用。

十六、问:Iterator是什么,有什么作用?<font color="#FF0000">(重要)</font>

答: Iterator是ES6中一个很重要概念,它并不是对象,也不是任何一种数据类型。因为ES6新增了Set、Map类型,他们和Array、Object类型很像,Array、Object都是可以遍历的,但是<font color="#DAA520">Set、Map都不能用for循环遍历</font>,解决这个问题有两种方案,一种是为Set、Map单独新增一个用来遍历的API,另一种是为Set、Map、Array、Object新增一个统一的遍历API,显然,第二种更好,ES6也就顺其自然的需要一种设计标准,来统一所有可遍历类型的遍历方式。Iterator正是这样一种标准。或者说是一种规范理念。

就好像JavaScript是ECMAScript标准的一种具体实现一样,Iterator标准的具体实现是<font color="#3CB371">Iterator遍历器</font>。Iterator标准规定,所有部署了key值为[Symbol.iterator],且[Symbol.iterator]的value是<font color="#3CB371">标准的Iterator接口函数(<font color="#FF0000">标准的Iterator接口函数</font>: 该函数必须返回一个对象,且对象中包含next方法,且执行next()能返回包含value/done属性的<font color="#FF0000">Iterator对象</font>)</font>的对象,都称之为可遍历对象,next()后返回的Iterator对象也就是<font color="#3CB371">Iterator遍历器</font>。

ES6给Set、Map、Array、String都加上了[Symbol.iterator]方法,且[Symbol.iterator]方法函数也符合标准的Iterator接口规范,所以Set、Map、Array、String默认都是可以遍历的。

十七、问:for...in 和for...of有什么区别?

答: 如果看到问题十六,那么就很好回答。问题十六提到了ES6统一了遍历标准,制定了可遍历对象,那么用什么方法去遍历呢?答案就是用for...of。ES6规定,有所部署了载了Iterator接口的对象(可遍历对象)都可以通过for...of去遍历,而for..in仅仅可以遍历对象。

这也就意味着,数组也可以用for...of遍历,这极大地方便了数组的取值,且<font color="#DAA520">避免了很多程序用for..in去遍历数组的恶习</font>。

上面提到的扩展运算符本质上也就是for..of循环的一种实现。

十八、Generator函数是什么,有什么作用?

答: 如果说JavaScript是ECMAScript标准的一种具体实现、Iterator遍历器是Iterator的具体实现,那么Generator函数可以说是Iterator接口的具体实现方式。

执行Generator函数会返回一个遍历器对象,每一次Generator函数里面的yield都相当一次遍历器对象的next()方法,并且可以通过next(value)方法传入自定义的value,来改变Generator函数的行为。

Generator函数可以通过配合Thunk 函数更轻松更优雅的实现<font color="#3CB371">异步编程</font>和<font color="#3CB371">控制流管理</font>。

十九、async函数是什么,有什么作用?

答: async函数可以理解为内置自动执行器的Generator函数语法糖,它配合ES6的Promise<font color="#3CB371">近乎完美的</font>实现了异步编程解决方案。

二十、Class、extends是什么,有什么作用?

答: ES6 的class可以看作只是一个ES5生成实例对象的构造函数的语法糖。它参考了java语言,定义了一个类的概念,让对象原型写法更加清晰,对象实例化更像是一种面向对象编程。Class类可以通过extends实现继承。它和ES5构造函数的不同点:

a. 类的内部定义的所有方法,都是不可枚举的。

b.ES6的class类必须用new命令操作,而ES5的构造函数不用new也可以执行。

c.ES6的class类不存在变量提升,必须先定义class之后才能实例化,不像ES5中可以将构造函数写在实例化之后。

d.ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

二十一、module、export、import是什么,有什么作用?

答: module、export、import是ES6用来统一前端模块化方案的设计思路和实现方案。export、import的出现统一了前端模块化的实现方案,整合规范了浏览器/服务端的模块化方法,用来取代传统的AMD/CMD、requireJS、seaJS、commondJS等等一系列前端模块不同的实现方案,使前端模块化更加统一规范,JS也能更加能实现大型的应用程序开发。

import引入的模块是<font color="#3CB371">静态加载</font>(编译阶段加载)而不是动态加载(运行时加载)。

import引入export导出的接口值是<font color="#3CB371">动态绑定</font>关系,即通过该接口,可以取到模块内部实时的值。

二十二、日常前端代码开发中,有哪些值得用ES6去改进的编程优化或者规范?

答:

1、常用箭头函数来取代var self = this;的做法。

2、常用let取代var命令。

3、常用数组/对象的结构赋值来命名变量,结构更清晰,语义更明确,可读性更好。

4、在长字符串多变量组合场合,用模板字符串来取代字符串累加,能取得更好地效果和阅读体验。

5、用Class类取代传统的构造函数,来生成实例化对象。

6、在大型应用开发中,要保持module模块化开发思维,分清模块之间的关系,常用import、export方法。

(完)

(洋洋洒洒几乎全是手动打字,如果有错误之处,还请指正!)

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复