ES6常见面试题

3,672 阅读11分钟

ES6是什么

ES6是新一代的JS语言标准,对JS核心内容做了升级优化。不仅规范了JS的使用标准,还新增了JS的原生方法,使得JS更加规范,更加适合大型应用的开发。

箭头函数

ES5、ES6、ES2015有什么区别

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

bable是什么,有什么作用

babel是一个ES6转码器,可以将ES6转化为ES5,兼容不支持ES6的平台

let var const的区别

  • let const 不会变量提升,而var可以
  • 相同作用域下,let const 不能重复声明,而var可以
  • const 声明一个只读常量,且必须有初始值,不可以变

举一些ES6String字符串类型做的常用升级优化

  • 优化部分

ES6新增了模板字符串,在拼接大段字符串,以反斜杠取代以前的相加方式,能保留所有空格和换行,是字符串拼接看起来更加直接美观。

  • 升级部分

ES6String原型上新增了includes方法,用于取代传统的indexOf方法。includes可直接返回true或者false,使语义更清晰,更加明确。此外还新增了startsWith()endWith()padWidth()padEnd()repeat()等方法,可方便的用于查找,补全字符串。

举一些ES6Array数组类型做的常用升级优化

  • 优化部分

ES6可以使用数组解构赋值,在声明较多变量时,不用再写很多let,而且映射关系更加清楚,支持默认值

扩展运算符,可以轻松方便的实现数组的复制和结构赋值。

  • 升级部分

新增了find方法,用于取代传统的indexOf,此外还新增了copyWithin(), includes(), fill(),flat()等方法,可方便的用于字符串的查找、补全、转换等。

举一些ES6Number数字类型做的常用升级优化

  • 优化部分

新增了isFinite() isNaN()方法。ES5会造成isNaN('NaN') === true的奇怪行为。而ES6不会造成这种现象

  • 升级部分

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

举一些ES6Object对象做的常用升级优化

  • 优化部分
  1. ES6直接以变量形式声明对象属性或方法,比传统的键值对方式更加简洁更加方便
  2. 对象的解构赋值
  3. 对象的扩展运算符
  4. super关键字,ES6class新增了类似this的关键词super。同this当前函数所在的对象不同,super总是指向当前函数所在对象的原型对象
  • 升级部分
  1. ES6Object原型上新增了is方法,做两个目标对象的相等比较。用来完善===方法,'==='方法中NaN === NaN //false 其实是不合理的,Object.is修复了这个小bug。

  2. ES6Object原型上新增了assign()方法,用于对象新增属性或者多个对象合并

  3. ES6Object原型上新增了getOwnPropertyDescriptors()方法,此方法增强了ES5getOwnPropertyDescriptor()方法,可以获取指定对象所有自身属性的描述对象。结合defineProperties()方法,可以完美复制对象,包括复制getset属性

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

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

举一些ES6Function函数做的常用升级优化

  • 优化部分
  1. 箭头函数(核心)。箭头函数是ES6核心的升级项之一,箭头函数里没有自己的this,这改变了以往JS函数中最让人难以理解的this运行机制
  • 箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象ES5函数里的this总是指向函数执行时所在的对象,这使得在很多情况下this的指向变得很难理解,尤其是非严格模式情况下,this有时候会指向全局对象,这甚至也可以归结为语言层面的bug之一。ES6的箭头函数优化了这一点,它的内部没有自己的this,这也就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己this的函数为止,并作为自己的this

  • 箭头函数不能用作构造函数,因为它没有自己的this,无法实例化

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

  1. 函数默认赋值ES6之前,函数的形参是无法给默认值得,只能在函数内部通过变通方法实现。ES6以更简洁更明确的方式进行函数默认赋值
  • 升级部分
  1. ES6新增了双冒号运算符,用来取代以往的bindcall,和apply。(浏览器暂不支持,Babel已经支持转码)
  •   foo::bar;
      // 等同于
      bar.bind(foo);
      
      foo::bar(...arguments);
      // 等同于
      bar.apply(foo, arguments);
    

Symbol是什么,有什么作用

SymbolES6引入的新的数据类型,它生成的值时独一无二的,从根本上解决属性太多导致属性名冲突覆盖的问题。

Set是什么,有什么作用

SetES6引入的类似Arrary的一种新的数据结构,Set实例的成员类似于数组item成员,区别是Set实例的成员都是唯一,不重复的。这个特性可以轻松地实现数组去重。

Map是什么,有什么作用

MapES6引入的类似Object的一种新的数据结构,Map可以理解为是Object的超集,打破了以传统键值对形式定义对象,对象的key不再局限于字符串,也可以是Object。可以更加全面的描述对象的属性。

Proxy是什么,有什么作用

ProxyES6新增的一个构造函数,可以理解为JS语言的一个代理,用来改变JS默认的一些语言行为,包括拦截默认的get/set等底层方法,使得JS的使用自由度更高,可以最大限度的满足开发者的需求

Reflect是什么,有什么作用

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

Promisse是什么,有什么作用

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

Iterator是什么,有什么作用

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

ES6SetMapArrayString都加上了[Symbol.iterator]方法,且[Symbol.iterator]方法函数也符合标准的Iterator接口规范,所以SetMapArrayString默认都是可以遍历的。

for...in 和for...of有什么区别

所有Iterator接口的对象(可遍历对象)都可以通过for...of去遍历,而for..in仅仅可以遍历对象。

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

Generator函数是什么,有什么作用

Generator函数可以说是Iterator接口的具体实现方式,Generator函数可以通过配合Thunk 函数更轻松更优雅的实现异步编程和控制流管理

async函数是什么,有什么作用

async函数可以理解为内置自动执行器的Generator函数语法糖,它配合ES6Promise近乎完美的实现了异步编程解决方案

Classextends是什么,有什么作用

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

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

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

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

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

module、export、import是什么,有什么作用

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

import引入的模块是静态加载(编译阶段加载)而不是动态加载(运行时加载)。

import引入export导出的接口值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

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

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

2、常用let取代var命令。

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

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

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

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