ES6核心知识总结

一、let和const命令

let不存在变量提升

var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。let命令改变了语法行为

    // var 的情况
    console.log(foo); // 输出undefined
    var foo = 2;

    // let 的情况
    console.log(bar); // 报错ReferenceError
    let bar = 2;
复制代码

let会形成块级作用域

一般认为块级作用域就是使用{}包起来的块。变量只在这个块里起作用

    {
        let a = 1;
    }
    console.log(a);// 报错,a is not defined
复制代码

块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了,来,说一道面试题

    var funcs = []
    for (var i = 0; i < 10; i++) {
        funcs.push(function() { console.log(i) })
    }
    funcs.forEach(function(func) {
        func()
    })
复制代码

这样的面试题是大家很常见,很多同学一看就知道输出十次10 但是如果我们想依次输出0到9呢?

    // 再来看看es6怎么处理的
    const funcs = []
    for (let i = 0; i < 10; i++) {
        funcs.push(function() {
            console.log(i)
        })
    }
    funcs.forEach(function(func) {
        func()
    })
复制代码

达到相同的效果,ES6 简洁的解决方案是不是更让你心动!!!

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”简称 TDZ

    if (true) {
     // TDZ开始
     tmp = 'abc'; // ReferenceError
     console.log(tmp); // ReferenceError

     let tmp; // TDZ结束
     console.log(tmp); // undefined

     tmp = 123;
     console.log(tmp); // 123
    }
复制代码

不允许重复声明

let不允许在相同作用域内,重复声明同一个变量

    // 报错
    function func() {
     let a = 10;
      var a = 1;
    }

    // 报错
    function func() {
     let a = 10;
     let a = 1;
    }
复制代码

const基本用法

const声明一个只读的常量。一旦声明,常量的值就不能改变,

    const PI = 3.1415;
    PI // 3.1415

    PI = 3;
    // TypeError: Assignment to constant variable.
复制代码

我们通常用 let 和 const 来声明,let 表示变量、const 表示常量。const的作用域与let命令相同:只在声明所在的块级作用域内有效,const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用,const声明的常量,也与let一样不可重复声明。

const本质

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

    const a = [];
    a.push('Hello'); // 可执行
    a.length = 0;    // 可执行
    a = ['Dave'];    // 报错
复制代码

上面代码中,常量a储存的是一个地址,这个地址指向一个数组。不可变的只是这个地址,即不能把a指向另一个地址,但数组本身是可变的,如果将另一个数组赋值给a,就会报错。

二、变量的解构赋值

数组的解构赋值

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3
复制代码

解构赋值允许指定默认值.

let [x, y = 'b'] = ['a']; // x='a', y='b'
复制代码

如果解构不成功,变量的值就等于undefined。

let [foo] = [];
let [bar, foo] = [1];
复制代码

对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
复制代码

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
复制代码

解构赋值的用途

(1)交换变量的值

let x = 1;
let y = 2;

[x, y] = [y, x];
复制代码

(2)从函数返回多个值

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

// 返回一个对象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();
复制代码

三、模板字符串

模板字符串使用十分方便,经常用于输出一个结果。举个例子

var name = "小强"
console.log("我的名字叫"+name)
//模板字符串表达
console.log(`我的名字叫${name}`)
复制代码

四、箭头函数

ES6 允许使用“箭头”(=>)定义函数

var f = function (v) {
  return v*v;
};
//转化为箭头函数如下
var f = (v)=>{
    return v*v;
}
//当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略{} 和 return
var f = v => v*v;
复制代码

五、数组的扩展

扩展运算符

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
复制代码

扩展运算符的应用

(1)复制数组 (注意:使用扩展运算符复制一个数组属于深拷贝,两个数组之间互相独立,改变其中一个的值不会影响另一个的值)

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)与解构赋值结合

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]

const [first, ...rest] = ["foo"];
first  // "foo"
rest   // []
复制代码

(4)扩展运算符还可以将字符串转为真正的数组

[...'hello']
// [ "h", "e", "l", "l", "o" ]
复制代码

Array.from()

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

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

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

值得提醒的是,扩展运算符(...)也可以将某些数据结构转为数组。

Array.of()

Array.of方法用于将一组值,转换为数组。

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
复制代码

这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

数组实例的 find() 和 findIndex()

数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。

[1, 4, -5, 10].find((n) => n < 0)
// -5
复制代码

数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2
复制代码

数组实例的 fill()

fill方法使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]
复制代码

fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
复制代码

上面代码表示,fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束。

数组实例的 includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。

[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true
复制代码

六、class

class创建类

(1)class 是关键字,后面紧跟类名,类名首字母大写,采取的是大驼峰命名法则。类名之后是{}。

(2)在{}中,不能直接写语句,只能写方法,方法不需要使用关键字

(3)方法和方法之间没有逗号。不是键值对

举个栗子:

class NBAPlayer{
    constructor(name,age,height){
        this.name = name
        this.age = age
        this.height = height
    }
    say(){
        console.log(`我是${this.name},我今年${this.age},我的身高${this.height}`)
    }
}
var rs = new NBAPlayer("姚明","35","226")
rs.say()
复制代码

使用extends实现继承

注意:在子类中的构造器 constructor 中,必须要显式调用父类的 super 方法,如果不调用,则 this 不可用

class NBAPlayer{
    constructor(name,age,height){
        this.name = name
        this.age = age
        this.height = height
    }
    say(){
        console.log(`我是${this.name},我今年${this.age},我的身高${this.height}`)
    }
}
class MVP extends NBAPlayer{
    constructor(name,age,height,year){
        super(name,age,height)
        this.year = year
    }
    sayi(){
        console.log(`我是${this.name},我在${this.year}拿MVP`)
    }
}
var rs = new MVP("姚明","35","226","2014")
rs.say()
rs.sayi()
复制代码

七、set和map

(1)set

set和数组差不多,也是一种集合,区别在于:它里面的值都是唯一的,没有重复的。Set 本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
  console.log(i);
}
// 2 3 5 4
复制代码

上面代码通过add方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。for of 一种遍历方式

// 去除数组的重复成员
[...new Set(array)]
复制代码

(2)map

它类似于对象,里面存放也是键值对,区别在于:对象中的键名只能是字符串,如果使用map,它里面的键可以是任意值。

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false
复制代码

上面代码使用 Map 结构的set方法,将对象o当作m的一个键,然后又使用get方法读取这个键,接着使用delete方法删除了这个键

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"
复制代码

作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

八、严格模式

JS语法非常灵活,JS中这个灵活的特性,弊大于先利。后来增加了严格模式。使用严格模式的目的:规则,提高编译效率。

怎么去启动严格模式: "use strict"

严格模式和非严格模式有什么区别:

1.在严格模式下不能使用没有var的变量

2.在严格模式下不能8进制的数字

3.在严格模式下不能把函数定义在if语句中

4.在严格模式下函数不能有重名的形参

5.在严格模式下不能arguments就不能使用了

6.在严格模式下不能function中的this就再在是window

初学ES6,文章有误请指点,文内部分用词不准确也请谅解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值