ES6新特性

218 阅读4分钟

数据结构 Map 和 Set

跟数组和对象一样,mapset也是javascript的复杂数据结构

Map

MapObject一样,都是带有键的数据集合,跟Object最大的区别就是Map的键可以是任何类型,其常用属性和方法:

  • map.size-------------------- 集合中元素的个数
  • map.get(key)--------------- 查看key的值,若集合中不存在key属性,则返回undefined
  • map.set(key, value)------- 添加键值对
  • map.has(key)--------------- 检测集合中是否存在key属性,若存在,返回true,否则false
  • map.delete(key)------------ 删除集合中key属性
  • map.clear() ---------------- 清空map 举个栗子:
// 创建一个 map
let map = new Map()

// Map 的键可以是任何类型, Object 则会自动转换成字符串
map.set('11', 'str')    // 键可以是字符串
map.set(11, 'num')      // 也可以是数字
map.set(true, 'bool')   // 也可以是布尔值

alert(map.size)         // 3
alert(map.get(11))      // num
alert(map.get(true))    // bool

注意: Map中不能使用map.key=value或者map['key']=value的方式添加属性,应该使用mapsetget 等方法

Map 还可以将对象作为键

let key = { name: 'jams' }

let map = new Map()
map.set(key, 111)
alert(map.get(key))    // 111

Set

Set是一组保存唯一值的集合,与数组最大的区别是Set里面的值只允许出现一次, 有以下常用属性和方法:

  • set.size------------------元素个数
  • set.add(value)-----------添加值(如果已存在value则不做任何操作), 返回值为set本身
  • set.delete(value)--------删除值(若存在,返回true,否则false)
  • set.has(value)-----------检测是否存在value,若存在,返回true, 否则false
  • set.clear()--------------清空set
// 创建 set 
let set = new Set()

set.add('red')
set.add('blue')
set.add('green')
set.add('red')     // 因为已存在'red',无效的操作

for(let key of set) {
    alert(key)     // red --> blue --> green
}

Set的这种特性被用来数组去重

let arr = ['red', 'green', 'blue', 'green', 'blue', 'red']

// 世上最简洁的数组去重方式
let newArr = [...new Set(arr)]
console.log(newArr)    // ["red", "green", "blue"]

const 和 let

const

  1. 当可以确定这个变量永远不会改变的时候,就可以使用const来申明
  2. 使用大写字母和下划线来命名这些常量,以清楚地告知后来的开发者
  3. 常用于定义第三方模块或者常数(16进制的颜色,PI等)的变量
const COLOR_WHITE = '#FFF'

COLOR_WHITE = '#EEE'   // 报错, 不能给常量重新赋值

let 和 var

1. var没有块级作用域

var声明的变量不是全局作用域就是函数作用域,没有块级作用域

if (true) {
    var test = 'hello'
}
alert (test)     // hello

此时var会忽略代码块,因此此时test变量是作为一个全局变量存在
如果用let声明,则只能在if内部访问

if (true) {
    let test = 'hello'
}
alert (test)     //  报错, test is not defined

var声明的变量在循环结构中也是这样:

for(var i = 0; i < 10; i++) {
    var test = 'hello'
}
alert (i)      // 10
alert(test)    // hello

var声明的变量存在函数作用域:

function sayHi() {
    var test = 'hello'
    console.log(test)   // hello
}
sayHi()
alert(test)     // 报错, test is not defined
2. var允许被重新声明
var test = 'hello'
var test = '你好'

alert(test)    // 你好

var声明的变量可被重新赋值,而let则会报错

let test = 'hello'
let test = '你好'

alert(test)    // 报错, 'test'已经被声明
3. var存在变量提升
alert(test)    // undefined
var test = 'hello'

可以看到,这段代码,不会报错,其实相当于下面这段代码:

var test
alert(test)    // undefined
test = 'hello'

模板字符串

解构赋值

JavaScript中,ArrayObject是使用最多的数据类型,但是我们很多时候不需要使用到集合内部所有的数据,而是需要使用到其中的某一些数据,因此解构赋值可以让我们将数组/对象"拆包"为一系列变量中,因为使用变量可能会更方便一点.

数组解构

let arr = ['刘备', '关羽', '张飞', '黄忠', '赵云']

let [one, two, three, four, five] = arr
alert(one)        // 刘备
alert(two)        // 关羽
alert(three)      // 张飞
alert(four)       // 黄忠
alert(five)       // 赵云

如果只需要其中的某一些数据

let arr = ['刘备', '关羽', '张飞', '黄忠', '赵云']

let [, one, , , two] = arr
alert(one)        // 关羽
alert(two)        // 赵云

还可以这样:

let arr = ['刘备', '关羽', '张飞', '黄忠', '赵云']

let [one, two, three, ...four] = arr
alert(one)              // 刘备
alert(two)              // 关羽
alert(three)            // 张飞
console.log(four)       // ['黄忠', '赵云']

注意: 因为数组是一个有序的数据集合,因此在解构的时候,需要注意等号左侧必须和等号右侧有相同的结构

对象解构

let userinfo = {
    user_id: 1,
    username: '张三',
    password: '123456',
    hobbies: ['吃饭', '睡觉', '打豆豆']
}

let { username, hobbies } = userinfo

console.log(username)    // 张三
console.log(hobbies)     // ["吃饭", "睡觉", "打豆豆"]

对象的解构中,变量的顺序不再重要,但是需要和对象中的属性名保持一致,如果会有变量命名冲突的情况,当然也可以将其赋值给新的变量名,比如这样:

let userinfo = {
    user_id: 1,
    username: '张三',
    password: '123456',
    hobbies: ['吃饭', '睡觉', '打豆豆']
}

let { username: name, hobbies: hobby } = userinfo

console.log(name)      // 张三
console.log(hobby)     // ["吃饭", "睡觉", "打豆豆"]

在解构的同时,也可以声明变量

let userinfo = {
    user_id: 1,
    username: '张三',
    password: '123456',
    hobbies: ['吃饭', '睡觉', '打豆豆']
}

let { username: name, hobbies: hobby, age = 18 } = userinfo

console.log(name)      // 张三
console.log(hobby)     // ["吃饭", "睡觉", "打豆豆"]
console.log(age)    // 18

...运算符在对象解构中同样适用

let userinfo = {
    user_id: 1,
    username: '张三',
    password: '123456',
    hobbies: ['吃饭', '睡觉', '打豆豆']
}

let { username: name, hobbies: hobby, ...info } = userinfo

console.log(name)      // 张三
console.log(hobby)     // ["吃饭", "睡觉", "打豆豆"]
console.log(info)      // {user_id: 1, password: "123456"}

扩展运算符(三点运算符)

Class 类

箭头函数

let func = function (x) {
    return x * x
}

// 将 func 函数用箭头函数进行改造
let func = (x) => {
    return x * x
}

// 若函数体只有一行代码, 可将大括号和 return 关键字省略不写
let func = (x) => x * x

// 若函数只有一个参数,小括号可以省略
let func = x => x * x

// 如果没有参数或者有多个参数,小括号则不能省略

使用箭头函数应注意:

  • 箭头函数没有自己的this对象,内部的this就是定义时上层作用域中的this
  • 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令
  • 箭头函数中没有arguments,如果要用,可以用rest参数代替。
let func = (...argus) => console.log(argus)   // [1, 2, 3]

func(1, 2, 3)

Promise 异步对象

jsnode中,都会使用回调函数嵌套的方式来解决异步操作返回结果的顺序不确定的问题,如果嵌套的层数特别多,就会形成回调地狱或者叫做横向金字塔,而Promise对象,就是用来解决这个问题的.

Promise 简介

  • Promise对象可以解决回调地狱的问题
  • Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大
  • Promise可以理解为一个容器,里面可以编写异步程序的代码
  • 从语法上说,Promise 是一个对象,使用的时候需要 new

简单使用

let promise = new Promise((resolve, reject) => {
    // 这里执行异步代码
    
})

模块 import 和 export