作者:Alex 译者:前端小智 来源:dev.to
ECMAScript 6(以下简称ES6)是 JS 语言的下一代标准,已经在2015
年6
月正式发布了。它的目标,是使得 JS 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。接下来咱们来看看 20 道棘手的面试题,通过做题,顺带提升一下咱们的 JS 的技能。
主题: JavaScript 难度: ⭐⭐⭐
ECMAScript 5 (ES5):ECMAScript 的第五版,于2009年标准化,该标准已在所有现代浏览器中完全支持。
ECMAScript 6 (ES6)/ ECMAScript 2015 (ES2015):ECMAscript 第 6 版,2015 年标准化。这个标准已经在大多数现代浏览器中部分实现。
以下是ES5和ES6之间的一些主要区别:
箭头函数和字符串插值
也可以这样写:
const:const
表示无法修改变量的原始值。需要注意的是,const
表示对值的常量引用,咱们可以改变被引用的对象的属性值,但不能改变引用本身。
块作用域:ES6 中 let
, const
会创建块级作用域,不会像 var
声明变量一样会被提升。
默认参数:默认参数使咱们可以使用默认值初始化函数。当参数省略或 undefined
时使用默认参数值。
类定义与继承
ES6 引入了对类(class
关键字)、构造函数(constructor
关键字)和 extend
关键字(用于继承)的语言支持。
for-of 运算符
for...of
语句创建一个遍历可迭代对象的循环。
展开操作符
Promises: Promises 提供了一种机制来处理异步操作的结果和错误。可以使用回调来完成相同的事情,但是Promises
通过方法链接和简洁的错误处理来提高可读性。
模块导出
和导入
import myModule from './myModule';
主题: JavaScript 难度: ⭐⭐⭐
IIFE
是一个立即调用的函数表达式,它在创建后立即执行
常常使用此模式来避免污染全局命名空间,因为在IIFE
中使用的所有变量(与任何其他普通函数一样)在其作用域之外都是不可见的。
主题: JavaScript 难度: ⭐⭐⭐
以下是一些经验分享:
Object.prototype
属性中使用 function
。class
。为啥大多数情况都使用箭头函数?
thisObject
。如果一个标准函数回调与一堆箭头函数混合在一起,那么作用域就有可能变得混乱。this
指向。主题: JavaScript 难度: ⭐⭐⭐
Symbol
是一种新的、特殊的对象,可以用作对象中惟一的属性名。使用 Symbol
替换string
可以避免不同的模块属性的冲突。还可以将Symbol
设置为私有,以便尚无直接访问Symbol
权限的任何人都不能访问它们的属性。
Symbol
是JS新的基本数据类型。与number
、string
和boolean
原始类型一样,Symbol
也有一个用于创建它们的函数。与其他原始类型不同,Symbol
没有字面量语法。创建它们的唯一方法是使用以下方法中的Symbol
构造函数
let symbol = Symbol();
主题: JavaScript 难度: ⭐⭐⭐
ES6 的展开语法在以函数形式进行编码时非常有用,因为咱们可以轻松地创建数组或对象的副本,而无需求助于Object.create,slice
或库函数。Redux
和rx.js
项目中经常使用此特性。
ES6 的 rest 语法提供了一种捷径,其中包括要传递给函数的任意数量的参数。
就像展开语法的逆过程一样,它将数据放入并填充到数组中而不是展开数组,并且它在函数变量以及数组和对象解构分中也经常用到。
主题: JavaScript 难度: ⭐⭐⭐
对于简单的构造函数,它们看起来非常相似。
构造函数的主要区别在于使用继承。如果咱们创建一个继承Person
类的Student
子类并添加一个studentId
字段,以下是两种方式的使用:
在 ES5 中使用继承要复杂得多,而且 ES6 版本更容易理解和记住。
主题: JavaScript 难度: ⭐⭐⭐
.call
和.apply
均用于调用函数,并且第一个参数将用作函数中this
的值。但是,.call
将逗号分隔的参数作为下一个参数,而.apply
将参数数组作为下一个参数。简单记忆法:C用于call
和逗号分隔,A用于apply
和参数数组。
主题: JavaScript 难度: ⭐⭐⭐
选择使用类的一些原因:
class
可以避免构造函数中使用new的常见错误(如果构造函数不是有效的对象,则使构造函数抛出异常)。super.method()
代替ParentConstructor.prototype.method.call(this)
或Object.getPrototypeOf(Object.getPrototypeOf(this)).method.call(this)
考虑下面代码:
使用 ES6 实现上述功能:
主题: JavaScript 难度: ⭐⭐⭐
可以 Object.freeze
来实现枚举
或者
但是,这阻止咱们把值分配给变量:
let day = DaysEnum.tuesday
day = 298832342 // 不会报错
主题: JavaScript 难度: ⭐⭐⭐
const
和Object.freeze
是两个完全不同的概念。
const
声明一个只读的变量,一旦声明,常量的值就不可改变:
Object.freeze
适用于值,更具体地说,适用于对象值,它使对象不可变,即不能更改其属性。
主题: JavaScript 难度: ⭐⭐⭐⭐
提升是指 JS 解释器将所有变量和函数声明移动到当前作用域顶部的操作,提升有两种类型
只要一个var
(或函数声明)出现在一个作用域内,这个声明就被认为属于整个作用域,并且可以在任何地方访问。
主题: JavaScript 难度: ⭐⭐⭐⭐
原型模式会创建新的对象,而不是创建未初始化的对象,它会返回使用从原型或样本对象复制的值进行初始化的对象。原型模式也称为属性模式。
原型模式有用的一个例子是使用与数据库中的默认值匹配的值初始化业务对象。原型对象保留默认值,这些默认值将被复制到新创建的业务对象中。
传统语言很少使用原型模式,但是JavaScript作为一种原型语言,在构建新对象及其原型时使用这种模式。
主题: JavaScript 难度: ⭐⭐⭐⭐
在 ES6 中,let
和const
跟 var
、class
和function
一样也会被提升,只是在进入作用域和被声明之间有一段时间不能访问它们,这段时间是临时死区(TDZ)。
主题: JavaScript 难度: ⭐⭐⭐⭐
不应该使用箭头函数一些情况:
this/arguments
时,由于箭头函数本身不具有this/arguments
,因此它们取决于外部上下文this
即对象本身。主题: JavaScript 难度: ⭐⭐⭐⭐
WeakMaps 提供了一种从外部扩展对象而不影响垃圾收集的方法。当咱们想要扩展一个对象,但是因为它是封闭的或者来自外部源而不能扩展时,可以应用WeakMap
。
WeakMap只适用于 ES6 或以上版本。WeakMap是键和值对的集合,其中键必须是对象。
WeakMaps的有趣之处在于,它包含了对map
内部键的弱引用。弱引用意味着如果对象被销毁,垃圾收集器将从WeakMap
中删除整个条目,从而释放内存。
主题: JavaScript 难度: ⭐⭐⭐⭐
function foo(){ }();
IIFE
代表立即调用的函数表达式。JS解析器读取函数foo(){}();
作为函数foo(){}
和();
,前者是一个函数声明,后者(一对括号)是尝试调用一个函数,但没有指定名称,因此它抛出Uncaught SyntaxError: Unexpected token
异常。
咱们可以使用void
操作符:void function foo(){ }();
。不幸的是,这种方法有一个问题。给定表达式的求值总是undefined
的,所以如果IIFE 函数有返回值,则不能使用它,如下所示:
主题: JavaScript 难度: ⭐⭐⭐⭐
模块模式通常用于命名空间,在该模式中,使用单个实例作为存储来对相关函数和对象进行分组。这是一个不同于原型设计的用例,它们并不是相互排斥,咱们可以同时使用它们(例如,将一个构造函数放在一个模块中,并使用new MyNamespace.MyModule.MyClass(arguments)
)。
构造函数和原型是实现类和实例的合理方法之一。它们与模型并不完全对应,因此通常需要选择一个特定的scheme
或辅助方法来实现原型中的类。
主题: JavaScript 难度: ⭐⭐⭐⭐⭐
当它们的键/值引用的对象被删除时,它们的行为都不同,以下面的代码为例:
执行上面的 IIFE,就无法再引用{x:12}
和{y:12}
。垃圾收集器继续运行,并从 WeakMa
中删除键b
指针,还从内存中删除了{y:12}
。
但在使用 Map
的情况下,垃圾收集器不会从Map
中删除指针,也不会从内存中删除{x:12}
。
WeakMap
允许垃圾收集器执行其回收任务,但Map
不允许。对于手动编写的 Map
,数组将保留对键对象的引用,以防止被垃圾回收。但在WeakMap
中,对键对象的引用被“弱”保留,这意味着在没有其他对象引用的情况下,它们不会阻止垃圾回收。
主题: JavaScript 难度: ⭐⭐⭐⭐⭐
柯里化是一种模式,其中一个具有多个参数的函数被分解成多个函数,当被串联调用时,这些函数将一次累加一个所需的所有参数。这种技术有助于使用函数式编写的代码更容易阅读和编写。需要注意的是,要实现一个函数,它需要从一个函数开始,然后分解成一系列函数,每个函数接受一个参数。
主题: JavaScript 难度: ⭐⭐⭐⭐⭐
如果咱们想要确保对象被深冻结,就必须创建一个递归函数来冻结对象类型的每个属性:
没有深冻结
深冻结
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dev.to/fullstackcafe/20-tricky-es6-interview-questions-to-revamp-your-javascript-skills-5a4o