ES6新增内容

1. let和const命令

1.1 语法

    var a = 6
    let a = 6
    const a = 6

1.2 实例

    如上语法;
    for(let i = 0; i < 6; i++) {
        // 操作
    }

1.3 拓展

1.3.1 变量提升
即变量在声明之前使用,值为 undefined。
var 有,let 和 const 没有。
推荐使用const和let定义变量,尽量不要使用var
// var
console.log(aa) // 输出 undefined

// let || const
console.log(aa) // 报错 ReferenceError , 表示当一个不存在(或尚未初始化)的变量被引用时发生的错误
let aa = 6
1.3.2 暂时性死区
在代码块内,使用let命令声明变量之前,该变量都是不可用的。

var aa = 123

if(true) {
    aa = 666 // 会报错 ReferenceError
    let aa
}

// 上述代码中,存在全局变量 aa , 但是在块级作用域内 let 又声明了一个局部变量 aa,导致 后者绑定了这个块级作用域,所以在当前作用域内,aa属于未声明就使用,会报错  ReferenceError
1.3.3 不允许重复声明
let不允许在相同作用域下,重复声明同一个变量。

function Fun() {
    let aa = 6
    let aa = 66  // 会报错
}

function Fun(age) {
    let age = 6 // 会报错
}

function Fun(age) {
    {
        let age = 6 // 不报错
    }
}

2. 变量的解构赋值

2.1 语法

2.1.1 数组的解构赋值

以前,为变量赋值,只能直接指定值。
let a = 1
let b = 2

ES6允许写成下面这样:
let [a, b] = [1, 2]

// 上面代码表示:可以从数组中提取值,按照对应位置,对变量赋值。
// 本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋值对应的值。
// 如果等号的右边不是数组,那么将会报错。

2.1.2 对象的解构赋值

// 对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { name, age, sex, hobby } = { name: '张三', sex: '女', age: 18 }
name // '张三'
age // 18
sex // '女'
hobby // undefined

2.1.3 字符串的解构赋值

字符串也可以解构赋值,这是因为 字符串被转换成了一个类似数组的对象
const [ a, b, c, d, e ] = 'hello'
a // 'h'
b // 'e'
c // 'l'
d // 'l'
e // 'o'

2.1.4 数字 和 布尔值的解构赋值

虽然,但是 这个东西没有什么学习的必要,就不提了

2.1.5 函数参数的解构赋值

function add([x, y]) {
    return x + y
}
add([1, 2]) // 3


2.2 实例

2.2.1 数组

let [a, [[b], c]] = [1, [[2], 3]]
a // 1
b // 2
c // 3

let [ , , c] = [1, 2, 3]
c // 3  

let [a, ...c] = [1, 2, 3, 4]
a // 1
c // [2, 3, 4]

let [a, b, ...c] = [1]
a // 1
b // undefined  如果解构不成功,变量的值就为 undefined
c // []

// 不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。
let [a, b] = [1, 2, 3]
a // 1
b // 2

// 解构赋值允许指定默认值
let [a = 1] = []
a // 1

let [a, b = 2] = [1]
a // 1
b // 2

// ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员 === undefined, 默认值才会生效。
let [a = 1] = [undefined]
a // 1
let [a = 1] = [null]
a // null

2.2.2 对象

const { log } = console
log('hello')  // hello

如:变量名和属性名不一致,必须写成下面这样
let { name: personName } = { name: '张三', age: 18 }
personName // '张三'
name // 报错 error: name is not defined
上面代码中, name 是匹配的模式,personName 才是变量。

// 嵌套模式
let obj = {
    person: [
        'Hello',
        {
            name: '张三',
        }
    ]
}
let { person, p: [say, { name }] } = obj
say // 'Hello'
name // '张三'
person // [ 'Hello', { name: '张三' } ]


2.3 拓展

2.3.1 交换变量的值

let x = 1
let y = 2
[x, y] = [y, x]

2.3.2 从函数返回多个值

// 返回一个数组
function example(){
    return [1, 2, 3]
}
let [a, b, c] = example()

// 返回一个对象
function example() {
    return {
        name: '张三',
        age: 18
    }
}
let { name, age } = example()

2.3.3 函数参数的定义

解构赋值可以很方便的将一组参数与变量名对应起来。

// 参数是一组有次序的值
function Fun([x, y, z]) { ... }
Fun([1, 2, 3])

// 参数是一组无次序的值
function Fun({x, y, z}) { ... }
Fun({ z: 3, x: 1, y: 2 })

2.3.4 输入模块的指定方法

const { SourceMapConsumer, SpurceNode } = require("source-map")

3. 模板字符串

const age = 18
// 原
const person = '张三' + age + '岁'
// 新
const person = `张三${age}岁`

4. 数值相关

4.1 数值分隔符

较长的数值允许使用下划线(_)作为分隔符,增加数值的可读性。
let num = 1_000_000_000

这个数值分隔符没有指定间隔的位数
123_00 === 12_300  // true
12345_00 === 1_234_500  // true

注意点:
- 不能放在数值的最前面或最后面。
- 不能两个或两个以上的分隔符连在一起。
- 小数点的前后不能有分隔符。
// 以下写法全都会报错
3_.141
3._141
123__456
_123
123_

4.2 一些方法

- Number.isNaN() 检查一个值是否为NaN
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
与传统全局方法isNaN()的区别:
isNaN()会先调用Number()将非数值的值转为数值,再进行判断,而Number.isNaN()只对数值有效

- Number.parseInt(), Number.parseFloat()
ES6 将全局方法 parseInt() 和 parseFloat(),移植到 Number 对象上,行为完全保持不变。
// ES5 的写法
parseInt('12.34')  // 12
parseFloat('123.45#') // 123.45

// ES6 的写法
Number.parseInt('12.34')  // 12
Number.parseFloat('123.45#') // 123.45

这样做的目的:逐步减少全局性方法,使得语言逐步模块化。

4.3 Math 对象的扩展

--- Math.trunc()
用于去处一个数的小数部分,返回整数部分。
Math.trunc(4.1)  // 4
Math.trunc(4.9)  // 4
Math.trunc(-4.1)  // 4
Math.trunc(-0.222)  // 0

对于非数值,Math.trunc内部使用Number方法将其先转为数值后返回。
Math.trunc('123.456')  // 123
Math.trunc(true)  // 1
Math.trunc(false)  // 0
Math.trunc(null)  // 0

对于空值和无法截取整数的值,返回NaN
Math.trunc(NaN)  // NaN

5. 函数的扩展

5.1 函数参数的默认值

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
function person(name, age = 18) {
    console.log(name, age)
}

person('张三') // 张三 18
person('张三', 20)  // 张三 20
person('张三', '')  // 张三

5.2 rest参数 — 剩余参数

ES6 引入 rest参数(形式为 ...变量名),用于获取函数的多余参数,这样就不需要使用 arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

// 求和函数案例
function add(...values) {
    let sum = 0
    
    for(let val of values) {
        sum += val
    }
    
    return sum
}
add(2, 5, 3)  // 10

// 注意点:
--- rest参数 之后不能再有其他参数(即只能是最后一个参数),否则会报错
// 会报错
function Fun(a, ...b, c) {
    
}

5.3 箭头函数

--- 基本用法
ES6 允许使用箭头( => )定义函数

let Fun = a => a
// 等同于
let Fun = function(a) {
    return a
}

let Fun = () => 5
// 等同于
let Fun = function () {
    return 5
}

let Sum = (num1, num2) => num1 + num2
// 等同于
let Sum = function(num1, num2) {
    return num1 + num2
}

注意点:
--- 箭头函数没有自己的this对象。
箭头函数你内部的this就是定义时上层作用域中的this。
--- 不可以当做构造函数,也就是说,不可以对箭头函数使用new命令,否则会报错。
--- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以使用 rest参数代替。

6.数组的扩展

6.1 扩展运算符 (…)

console.log(...[1, 2, 3])  // 1 2 3
应用:
--- 1.复制数组
ES5 
const a1 = [1, 2]
const a2 = a1.concat()

ES6
const a1 = [1, 2]
const a2 = [...a1]
或者
const [...a2] = a1

--- 2.合并数组
const arr1 = ['a', 'b']
const arr2 = ['c']
const arr3 = ['d', 'e']

// ES5 的数组合并
arr1.concat(arr2, arr3)  // [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的数组合并
[...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]

--- 3.字符串
扩展运算符还可以将字符串转为真正的数组
[...'hello'] // [ 'h', 'e', 'l', 'l', 'o' ]

6.2 Array.from()

Array.from() 方法用于将两类对象转为真正的数组:类似数组的对象 和 可遍历的对象。

下面是一个类似数组的对象

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}
// ES5 的写法
let arr1 = [].slice.call(arrayLike)  // ['a', 'b', 'c']

// ES6 的写法
let arr2 = Array.from(arrayLike) // ['a', 'b', 'c']

6.3 Array.of()

Array.of() 方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3, 11, 8]
Array.of(3) // [3]
Array.of(3).length // 1

6.4 实例方法:find() findIndex() findLast() findLastIndex()

--- 1. find()
用于找出第一个符合条件的数组成员。
返回值:符合条件 -> 第一个符合条件的成员; 不符合 -> undefined。
[1, 4, -5, 10].find((x, i, arr) => x < 0)  // -5
上面代码中, find() 方法的回调函数可以接收三个参数,依次为 当前的值、当前的下标、原数组。

--- 2. findIndex()
返回值:符合条件 -> 第一个符合条件的成员的下标; 不符合 -> 返回 -1。
[1, 5, 10, 15].findIndex((x, i, arr) => x > 9) // 2

--- 3.findLast() 和 findLastIndex() 
从数组的最后一个成员开始,依次向前检查,其他与上面两个方法保持不变。

6.5 实例方法:includes()

该方法的第一个参数标识要搜索的值,第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为 -4, 但数组长度为3),则会重置为从0开始。
[1, 2, 3].includes(3, 3) // false
[1, 2, 3].includes(3, -1)  // true

6.6 实例方法:flat() flatMap()

--- 1.flat()
[1, 2, [3, 4]].flat()  // [1, 2, 3, 4]
默认只会拉平一层。
可以将falt() 方法的参数写成一个整数,表示想要拉平的层数。
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
当然,如果我们不知道有多少层嵌套,都想转成一维数组,可以用 Infinity 关键字作为参数。
[1, [2, [3]]].flat(Infinity)   // [1, 2, 3]

--- 2.flatMap()
flatMap()方法会对原数组的每个成员执行一个函数(类似于map()方法),然后对返回值组成的数组执行 flat()方法。
该方法返回一个新数组,不改变原数组。
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]

6.7 实例方法:at()

接收一个整数作为参数,返回对应位置的成员,支持 负索引。
const arr = [5, 12, 8, 130, 44]
arr.at(2) // 8
arr.at(-2)  // 130
// 如果参数位置超过了数组范围,返回 undefined
arr.at(-100)  // undefined
arr.at(100)  // undefined

7. 对象的扩展

7.1 属性的简洁表示法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
const name = '张三'
const person = {name}
person // {name: '张三'}

// 等同于 
const person = {name: '张三'}

7.2 Object.assign()

用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。
第一个参数为目标对象,后面的参数都为源对象。
注意:如果目标对象与源对象有同名属性,则后面的属性会覆盖前面的属性。
例:
const obj1 = { a: 1, b: 1 }
const obj2 = { b: 2, c: 2 }
const obj3 = { c: 3 }
Object.assign(obj1, obj2, obj3)
obj1 // { a: 1, b: 2, c: 3 }

8. 运算符的扩展

8.1 指数运算符(**)

2 ** 2 // 4  2*2
2 ** 3 // 8  2*2*2

特点:右结合,即多个指数运算符连用时,是从最右边开始计算的。
例:
2 ** 3 ** 2 // 512 相当于 2 ** (3 ** 2)

指数运算符可以与等号结合,形成一个新的赋值运算符(**=)
例:
let a = 1.5
a **= 2   // 等同于 a = a*a

let b = 4
b **= 3  // 等同于 b = b *b * b

8.2 链判断运算符 可选链(?.)

let person = {
    name: '张三'
}
person?.age  // undefined 不加? 就会报错

8.3 Null 判断运算符(??)

只有运算符左侧的值为 null 或 undefined 时,才会返回右侧的值。
let person = {
    name: '张三'
}
let personAge = person?.age ?? 0

8.4 逻辑赋值运算符

// 或赋值运算符
x ||= y  等同于 x || (x = y)

// 与赋值运算符
x &&= y  等同于 x && (x = y)

// Null 赋值运算符
x ??= y  等同于  x ?? (x = y)
这三个运算符 相当于先进行逻辑运算,然后根据运算结果,再根据情况进行赋值运算。
let person = {
    name: '张三'
}
// 老写法 
person.age = person.age || 18
// 新写法
person.age ||= 18

9. Set 和 Map 数据结构

9.1 Set

ES6提供了一个新的数据结构 Set。类似于数组,但是成员的值都是唯一的,没有重复的值。
Set 本身是一个构造函数,用来生成Set数据结构。
例:
去重
const set = new Set([1, 2, 3, 4, 4])
[...set]  // [1, 2, 3, 4]



9.2 Map

类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。是一种更完善的 Hash 结构实现。
const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

10. Promise

点击参考链接跳转

11. async/await

点击参考链接跳转

12. Class

12.1 Class的基本语法

12.1.1 类的由来

JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

ES6引入了 Class(类)这个概念,我们可以通过Class关键字,来定义类。
例:上面的传统方法用ES6的Class改写

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

// 上面代码定义了一个“类”,里面有一个 constructor()方法,就是构造方法,而this关键字则代表实例对象。
Point类除了构造方法,还定义了一个 toString()方法。

--- 使用时,也是直接对类使用 new 命令,跟构造函数的用法完全一致。
class Bar {
    doStuff() {
        console.log('stuff')
    }
}
const b = new Bar()
b.doStuff()  // 'stuff'
构造函数的 prototype 属性,在ES6的“类”上继续存在。事实上,类的所有方法都定义在类的 prototype属性上面。

12.1.2 constructor()

constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。

class Point {
    
}
// 等同于
class Point {
    constructor() {}
}

constructor()方法默认返回实例对象(即this),也可以指定返回另外一个对象。

class Foo {
  constructor() {
    return Object.create(null);
  }
}

new Foo() instanceof Foo
// false

上面代码中,constructor()函数返回一个全新的对象,结果导致实例对象不是Foo类的实例。

12.1.3 类的实例

生成类的实例的写法,使用new命令,如果不加new调用class,将会报错。

12.1.x 类的详细信息参考

点击参考链接跳转

12.2 Class的继承

点击参考链接跳转

13. Module

export
import
咱们现在写的 Vue代码都是采取的模块化处理。

END

参考链接:
ECMAScript 6 入门(阮一峰)
ECMAScript 当前的所有提案
EXPLORING ES6
你会用ES6,那倒是用啊!
20分钟上手ES6,不会ES6好意思说自己会JS ?

  • 34
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值