前端面试必备 ES6 全方位总结
大家好,我是魔王哪吒,话不多说,今天带来的是一篇《前端面试必备 ES6 全方位总结》文章,欢迎大家喜欢。
前言
学习 ES6 需要掌握的路线,了解什么是 ECMAScript 概述,了解 Symbol 数据类型,掌握 let 和 const,以及变量的解构赋值,Set 和 Map 的原理。
什么叫做箭头函数,ES6 对于 ES5 都有哪些扩展,ES6 的一些高级操作。
为了方便查看学习,我做了思维导图,如下图所示:
ESMAScript 概述
ECMAScript 是一种脚本程序设计语言,被称为 JavaScript 或是 JScript。它的中文名为ECMAScript
,英文名为European Computer Manufacturers Association Script
,我们可以简称为ES6
,其特点是万维网上应用广泛。
ECMAScript 是网景的布兰登·艾克开发的一种脚本语言的标准化规范,最初命名为 Mocha,后来改名为 LiveScript,最后重命名为 JavaScript。
1995 年 12 月,升阳与网景联合发表了 JavaScript。1996 年 11 月,网景公司将 JavaScript 提交给欧洲计算机制造商协会进行标准化。ECMA-262 的第一个版本于 1997 年 6 月被 Ecma 组织采纳。
ECMA Script 是 ECMA-262 标准化的脚本语言的名称。尽管 JavaScript 和 JScript 与 ECMAScript 兼容,但包含超出 ECMA Script 的功能。
ECMAScript 是一种可以在宿主环境中执行计算并能操作可计算对象的基于对象的程序设计语言。ECMAScript 最先被设计成一种 Web 脚本语言,用来支持 Web 页面的动态表现以及为基于 Web 的客户机—服务器架构提供服务器端的计算能力。
作为一种脚本语言,ECMAScript 具备同其他脚本语言一样的性质,即“用来操纵、定制一个已存在系统所提供的功能,以及对其进行自动化”。
ECMAScript 和 JavaScript 是什么关系呢?
简单来生活,ECMAScript 是 JavaScript 语言的国际标准,JavaScript 是 ECMAScript 是 ECMAScript 的实现。
Symbol 数据类型
ES6 引入一种新的原始数据类型为 Symbol ,表示为 独一无二 的值,用来定义独一无二的对象属性名。
Symbol 的讲解
4 个方面说说 Symbol 数据类型:
Symbol 的定义;
Symbol 作为对象属性名;
Symbol 使用场景;
Symbol 获取。
Symbol 的定义
一种 Symbol 类型可以通过使用 Symbol()函数来生成;
Symbol()函数可以接收一个字符串作为参数
示例代码:
let s1 = Symbol('web');
let s2 = Symbol('web');
console.log(s1 === s2);
console.log(typeof s1);
console.log(typeof s2);
chrome 截图:
由图可知:Symbol()函数接收的参数相同,其变量的值也不同,s1 和 s2 是 Symbol 类型的变量,因为变量的值不同,所以打印的结果为 false。使用 typeof 来获取相应的类型,所以打印的结果都为 symbol。
Symbol 作为对象属性名
Symbol 可以通过三种方式作为对象属性名。
第一种:
示例代码:
let symbol = Symbol();
let a = {};
a[symbol] = 'web';
由代码可知:首先声明了一个 Symbol 类型的变量 symbol,一个空的对象为 a,通过 a[symbol]给 a 对象赋值一个 web 的字符串。表示 symbol 作为对象属性名,web 作为它的属性值。
第二种:
示例代码:
let symbol = Symbol();
let a = {
[symbol]:'web'
};
由代码可知:首先声明了一个 Symbol 类型的变量 symbol,接着在声明对象 a 的同时通过[symbol]给 a 对象性赋值为 web 的字符串。
第三种:
示例代码:
let symbol = Symbol();
let a = {};
Object.defineProperty(a, symbol, {value: 'web'});
由代码可知:首先声明了一个 Symbol 类型的变量 symbol,一个空对象为 a,通过 Object.defineProperty()方法给 a 对象赋值为 web 的字符串。
Symbol 的值作为对象属性名,是不能用点运算符的。
Symbol 使用场景
一种有两种使用场景:
因为 Symbol 的值是均不相等的,所以 Symbol 类型的值作为对象属性名,不会出现重复。
代码形成强耦合的某一个具体的字符串。
Symbol 获取
通过 Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbols 属性名。
let 和 const
let 是 ES6 规范中定义用于声明变量的关键字。
使用 let 声明的变量有一个块级作用域范围。
为什么需要块级作用域?
为什么会添加这个块级作用域,就得了解 ES5 没有块级作用域时出现的问题。
场景一是内层变量可能会覆盖外层变量。
场景二是在 if 或者是 for 循环中声明的变量会泄漏成为全局变量。
场景一:
场景二:
代码示例:
if(true) {
var web = 'web';
}
console.log(web); // web 没在 iF 块中也可以访问
块级作用域的前提是进行 let 变量声明
独立的一对大括号,两个大括号之间就是变量的块级作用域的范围。
条件语句,函数声明语句,循环语句等的一对大括号中就是变量的块级作用域范围。
const 声明一个只读的常量。const 一旦声明常量,其值不能被改变。
const 和 let 只在声明的块级作用域内有效。否则会报错。
const 命令声明的常量只能在声明的位置后面使用。
const 声明的常量,与 let 一样不可重复声明。
变量的解构赋值
在 ES6 中可以从数组和对象中提取值,对变量进行赋值,称为解构赋值。
解构赋值就是只要等号两边的模式相同,左边的变量就会被对应赋值。
示例代码:
let [x,y='b'] = ['a'];
console.log(y); // b
let [x,y='b'] = ['a', undefined];
console.log(y); // b
let [x,y='b'] = ['a', null];
console.log(y); // null
解构赋值分类:
数组的解构赋值
对象的解构赋值
字符串的解构赋值
数字以及布尔值的解构赋值
函数参数的解构赋值
解构赋值的情况
两种情况:
完全解构
不完全解构
不完全解构
代码如下:
let [a = 1, b] = [];
// a = 1, b = undefined
数组的解构赋值
代码如下:
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
解构赋值允许指定默认值。
代码如下:
let [foo = true] = [];
foo // true
在使用默认值的时候,应该注意 undefined,因为 undefined 是不能赋值的。
代码如下:
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
对象解构
代码如下:
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
通过解构,我们可以很容易的把对象的方法复制给变量。
代码如下:
const { log } = console;
log('hello') // hello
或者是:
const { log:minelog } = console;
minelog ('hello') // hello
当我们使用解构赋值的时候,需要注意声明变量的作用域问题:
// 错误的写法
let x;
{x} = {x: 1};
// 正确的写法
let x;
({x} = {x: 1});
数组中是一个特殊的对象
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
不完全解构
let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = obj;
// x = undefined
// y = 'world'
剩余运算符
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
// a = 10
// b = 20
// rest = {c: 30, d: 40}
解构默认值
let {a = 10, b = 5} = {a: 3};
// a = 3; b = 5;
let {a: aa = 10, b: bb = 5} = {a: 3};
// aa = 3; bb = 5;
字符串解构
字符串本身也是一个对象,有时候,可以当成一个数组解构
代码如下:
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
当做一个对象解构
let {length : len} = 'hello';
len // 5
剩余运算符
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]
函数参数的解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
计算函数任意个参数之和:
代码:
function sum(...num){
var sumNum = 0;
for(let i=0;i<num.length;i++){
sumNum += parseInt(num[i])
}
console.log(sumNum)
}
Set 和 Map
Set 类似于数组,但是成员的值都是唯一的,没有重复的值。
Set 使用 add()方法添加元素,不会添加重复的值,所以 Set 可以对数组进行去重操作。
Map 类似于对象,键名的值可以是各种类型的值。
声明
使用 new Set()构造函数来声明 Set;
使用 new Map()构造函数来声明 Map。
使用 for...of 来遍历数组中的值
操作方法
共有的方法:delete 删除,has 有无,clear 清空。对于 Set 的添加操作是 add(),而 Map 是 set 设置和 get 获取。
has 是用来判断 Set 或者是 Map 中是否包含元素。
set 可以用来新增或者是修改 Map 中的元,只有 Map 有。
遍历方法
有 keys,values,entries,forEach。
keys 获取所有键,values 获取所有值,entries 获取所有键和值,forEach 遍历所有键和值。
箭头函数
ES6 中使用箭头函数(=>)来定义函数。
带参数的箭头函数
代码:
var single = a => a
single('web')
没有参数的箭头函数
代码:
var log = () => {
alert('web')
}
多个参数的箭头函数
代码:
var add = (a,b) => a+b
add(1,2)
es6 相对于 es5 的扩展
它主要分三种:
函数的扩展
对象的扩展
数组的扩展
函数的扩展
es6 中函数的扩展包含:默认值,剩余运算符,扩展运算符。
默认值
在 es5 中,函数的默认值设定是,通过“||”
进行设定的,当函数参数为undefine
时,取默认值。
在 es6 中,函数的默认值是写在参数定义的后面。
代码示例如下:
// es5
function log(x,y) {
y = y || 'web';
console.log(x,y);
}
function log(x,y="web"){
console.log(x,y);
}
剩余运算符
剩余运算符表示语句:...arrr
表示参数,指定的是可以有多个参数。
代码示例如下:
function web(...arr) {
for(let item of arr) {
console.log(item);
}
}
web(1,3,4,5,6);
扩展运算符
示例代码如下:
function add(a,b,c) {
console.log(a);
console.log(b);
console.log(c);
}
var arr = [1,2,3];
add(...arr);
对象的扩展
es6 中允许向对象直接写入变量和函数,作为对象的属性和方法。
es6 中允许使用表达式作为对象的属性,并且函数名称定义也可以采用相同的方式。
setter 和 getter。JavaScript 对象的属性是由名字,值和一组特性构成的。
es6 中对象的操作方法:
Object.is()
:比较两个值是否相等。
Object.assign()
:用于将对象进行合并。
Object.getOwnPropertyDescriptor
:返回对象属性的描述。
Object.keys()
返回一个数组,包含对象自身所有的可枚举属性。
数组的扩展
copyWithin(target,start,end)
:在当前数组内部,将指定位置的成员复制到其他位置,然后返回当前数组。
target
表示从该位置开始替换数据。如果是负值,表示倒数。
start
表示从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
end
表示到该位置前停止读取数据,默认等于数组长度。如果负值,表示倒数。
find()
表示用于找出第一个符号条件的数组成员。
findIndex()
表示返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
fill()
表示填充一个数组,fill()方法用于空数组的初始化。
includes()
表示该方法返回一个布尔值,表示某个数组是否包含给定的值。
es6 高级操作
Promise 对象用于表示一个异步操作的最终状态,完成或是失败。
Promise 是异步编程的一种解决方案,将异步操作以同步操作的流程表现出来,避免了多层回调函数嵌套问题。
一个 Promise 有几种状态:
pending
初始状态,既不是成功状态,也不是失败状态。fulfilled
表示操作成功完成。rejected
表示操作失败。
当其中任何一种情况出现时,Promise 对象的
then()
方法绑定的处理方法就会被调用。
then()
方法包含两个参数,onfulfilled
和onrejected
,他们都是function
类型。
当Promise
为fulfilled
状态时,调用then()
方法的onfulfilled
,当Promise
为rejected
状态时,调用then()
方法的onrejected
。
Promise.prototype.then
和Promise.prototype.catch
方法返回Promise
对象,所以它们可以被链式调用。
Iterator
Iterator 遍历器是一种接口,为各种不同的数据结构提供统一的访问机制。
任何数据结构只要部署了Iterator
接口,就可以完成遍历操作。
Iterator
的作用:
为各种数据结构,提供一个统一的,简便的访问接口。
使得数据结构的成员能够按某种次序排列。
ES6 创造了一种新的遍历命令 for...of 循环。
原生具备 Iterator 接口的数据结构,数组,某些类似数组的对象,Set 结构和 Map 结构。
Generator
Generator
是es6
提供的一种异步编程解决方案,在语法上,可以把它理解为一个状态机,内部封装了多种状态。
执行 Generator,会生成并返回一个遍历器对象。返回的遍历器对象,可以依次遍历 Generator 函数的每一个状态。
Generator
函数是一个普通的函数。
第一,function 关键字与函数名之间有一个*
号。
第二,函数体内使用yield
表达式来遍历状态。
代码如下:
function* newGenerator() {
yield 'web';
yield 'it';
return 'ending';
}
代码理解,执行 Generator 函数之后,并不会被立即执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。
使用遍历器对象的 Next()方法,使指针移向下一个状态。每一次调用 next()方法,内部指针就会从函数头部或上一次停下的地方开始执行,直到遇到下一个 yield 表达式位置。
Generator 是分段执行的,yield 表达式是暂停执行的标志,而 next()方法可以恢复执行。
next()函数带参数,该参数作为上一次 yield 表达式的返回值,因为 yield 本身是没有返回值的。
Class
ES6 引入 Class 类这个概念,使用 Class 关键字可以定义类。
示例代码:
class Person {
constructor(name,age){
this.name = name;
this.age = age;
}
say() {
return '名字:'+this.name+'年龄'+this.age+"岁";
}
}
var obj = new Person('web',12);
console.log(obj.say());
简单数据类型
ES5 中有 5 中简单数据类型,Undefined, Null, Boolean, Number, String.
Set
成员不能重复
只有健值,没有健名,有点类似数组。
可以遍历,方法有 add, delete,has
Set 实例属性
constructor: 构造函数
size:元素数量
代码如下:
let set = new Set([1, 2, 3, 2, 1])
console.log(set.length) // undefined
console.log(set.size) // 3
Set 实例方法
操作方法
add(value):新增,相当于 array 里的 push
delete(value):存在即删除集合中 value
has(value):判断集合中是否存在 value
clear():清空集合
遍历方法
keys():返回一个包含集合中所有键的迭代器
values():返回一个包含集合中所有值得迭代器
entries():返回一个包含 Set 对象中所有元素得键值对迭代器
forEach(callbackFn, thisArg):用于对集合成员执行 callbackFn 操作
Map
本质上是键值对的集合,类似集合
可以遍历,方法很多可以跟各种数据格式转换
Set 和 Map 主要的应用场景在于 数据重组 和 数据储存
Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构
Map 的属性及方法
属性:
constructor:构造函数
size:返回字典中所包含的元素个数
代码如下:
const map = new Map([
['name', 'web'],
['des', 'JS']
]);
map.size // 2
操作方法:
set(key, value):向字典中添加新元素
get(key):通过键查找特定的数值并返回
has(key):判断字典中是否存在键 key
delete(key):通过键 key 从字典中移除对应的数据
clear():将这个字典中的所有元素删除
遍历方法
Keys():将字典中包含的所有键名以迭代器形式返回
values():将字典中包含的所有数值以迭代器形式返回
entries():返回所有成员的迭代器
forEach():遍历字典的所有成员
字典(Map)
集合 与 字典 的区别:
共同点:集合、字典 可以储存不重复的值
不同点:集合 是以 [value, value]的形式储存元素,字典 是以 [key, value] 的形式储存
❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章
点赞、收藏和评论
我是Jeskson
(达达前端),感谢各位人才的:点赞、收藏和评论,我们下期见!(如本文内容有地方讲解有误,欢迎指出☞谢谢,一起学习了)
我们下期见!
文章持续更新,可以微信搜一搜「 程序员哆啦 A 梦 」第一时间阅读,回复【资料】有我准备的一线大厂资料,本文 http://www.dadaqianduan.cn/#/ 已经收录
github
收录,欢迎Star
:https://github.com/webVueBlog/WebFamily
版权声明: 本文为 InfoQ 作者【魔王哪吒】的原创文章。
原文链接:【http://xie.infoq.cn/article/ac97db68456f271d11219d1cc】。未经作者许可,禁止转载。
评论