Bootstrap

JavaScript之ES6

ES6

ECMAScript6.0(ES6),是JavaScript语言的新里程碑,于2015年6月正式发布,它的目标是使得JavaScript语言可以编写复杂的大型应用程序,成为企业级开发语言

  • 1997年:ES1
  • 1998年:ES2
  • 1999年:ES3巨大成功,放飞自由
  • 2006年:ES4未通过
  • 2009年:ES5
  • 2015年:ES6

let关键字和const关键字

let关键字用来声明变量,它不允许重复声明,不允许变量提升,具有变量作用域,不与顶层对象window挂钩

const关键字用来声明常量,其值不允许改变,必须初始化显示赋值,其他特性与let一样

const关键字声明的常量在赋值成对象时,对象的内容可以改变,freeze方法可以冻结对象,以实现其需求

解构赋值

let arr = [1, 2, 3]
// console.log(arr[0])
// 解构赋值
let [a, b, c] = arr
// 只拿某一个值
let [, , d] = arr

// 变量交换值
let x = 1
let i = 2
// 这里的分号非常重要
;[i, x] = [x, i]
console.log(x, i)

// 给一个默认值
let [e = 1] = []
console.log(e)
let obj = {
	name: '张三',
	age: 19,
	sex: '女',
    hobby: '乒乓球'
}
// 通过属性拿值
let {name, age} = obj
console.log(name, age)

// 可以重命名,a变量拿age的值
let {age:a} = obj
console.log(a)
let obj = {
	ame: '张三',
	data: {
		list: [1,2,3]
	}
}
// 嵌套拿值
let {data:{list:[x,y,z]}} = obj
console.log(x,y,z)

模板字符串

前面已经介绍过了,详细请看JavaScript基础,它也支持表达式

字符串扩展

includes函数

判断字符串中是否存在指定字符

let names = 'knxsd'
// 这三个方法有第二个参数,从哪里开始查
console.log(names.includes('x')) // true
// 判断是否以指定字符开头
console.log(names.startsWith('k')) // true
// 判断是否以指定字符结尾
console.log(names.endsWith('sd')) // true

repeat函数

可重复写字符

// repeat方法:重复方法
let a = 'aaa'
// 6个a
console.log(a.repeat(2))

数值扩展

支持二进制和八进制

// 支持二进制和八进制
let num1 = 100
// 十六进制
let num2 = 0x100
// 二进制
let num3 = 0b100
// 八进制
let num4 = 0o100

Number.isFinite()和Number.isNaN()

他们与传统的全局方法isFinite()和isNaN()区别在于,传统方法先调用Number将非数值转为数值,在进行判断,而这两个新方法只对数值有效

Number.isInteger()

判断是否为整数

Number.EPSILON属性

function isEquals(x, y){
  // Number.EPSILON 这是一个极小的常量,使我们允许的误差值
  return Math.abs(x - y) < Number.EPSILON
}

Math.trunc()

将小数部分去掉

console.log(Math.trunc(1.2)) // 1
console.log(Math.trunc(1.8))  // 1
console.log(Math.trunc(-1.2)) // -1
console.log(Math.trunc(-1.8)) // -1

Math.sign()

用来判断一个数是正数,负数,还是0,对于非数字,将其转换为数字

console.log(Math.sign(100)) // +1
console.log(Math.sign(-100)) // -1
console.log(Math.sign(0)) // +0
console.log(Math.sign(-0)) // -0
console.log(Math.sign('')) // NaN

数组扩展

扩展运算符

let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
// 复制
console.log([...arr1,...arr2])

Array.from()

将伪数组转换为数组

find()和findIndex()

let arr = [11, 22, 33, 44, 55]
arr.find(function(item) {
    // 查找大于15的元素
    return item > 15
})
let arr = [11, 22, 33, 44, 55]
arr.findIndex(function(item) {
    // 查找大于15的元素下标
    return item > 15
})

fill()

// 快速填充数组
let arr = new Array(3).fill('xsd')

flat()和flatMap()

扁平化处理数据:开发很实用啦

对象扩展

对象简写

/*let obj = {
    name: 'zhangsan',
    test1: function() {
        
    },
    test2: function() {
        
    }
}*/
let obj = {
    name: 'zhangsan',
    age,// age:age
    test1() {
        
    },
    test2() {
        
    }
}

对象属性可以写成变量

let name = 'a'
let obj = {
    // 属性可以写成变量
    [name]: 'zhansan'
}

扩展运算符

这是ES2018的内容,这里提一下

let obj = {
    name: '战士'
}
let obj1 = {
    ...obj
}

和以前的Object.assign()方法相似

Object.is()

Object.is(NaN, NaN) // true

函数扩展

函数参数默认值

// 这是默认值,不会影响实参
function ajax(url, method='get', async=true) {
    
}
ajax('/http://', 'get', true)

rest参数

function test(...data) {
    
}
test(1, 2, 3, 4, 5, 5, 6)

箭头函数

箭头函数this指向父作用域this

let test = () => {
  console.log('a')
}
test()

Symbol

ES6引入了一种新的数据类型即Symbol,表示独一无二的值

  1. 使用Symbol作为对象属性名
let name = Symbol()
let age = Symbol()
let obj = {
    [name]: 'zhansan',
    [age]: 100
}
// 拿到对象的Symbol属性
console.log(Object.getOwnPropertySymbols())

它不能进行运算

Symbol可以隐式转换为true

可以给它传递一个参数以标记

Iterator迭代器

Iterator迭代器的作用有三个

为各种数据结构提供一个统一的简便的访问接口

二是使得数据结构的成员能够按某种次序排列

ES6创建了一种新的遍历命令,Iterator主要供for…of…循环

let arr = [1, 2, 3, 4]
for(let i of arr) {
    console.log(i)
}

Iterator的遍历流程

  1. 创建一个指针对象,指向当前数据结构的起始位置,也就是说,遍历器对象本质就是一个指针对象
  2. 第一次调用指针对象的next()方法,可以移动指针,依次类推
  3. 直到指针指向结束时,结束遍历
let i = arr[Symbol.iterator]()
console.log(i.next())
console.log(i.next())
console.log(i.next())
console.log(i.next())
console.log(i.next())

ES6规定:默认的Iterator接口部署在数据结构的Symbol.iterator属性上,或者说一个数据结构只要具有Symbol.iterator属性,就可以认为是可遍历的,Symbol.iterator属性本身是一个函数,即当前数据结构默认的遍历器生成函数,执行这个函数,就返回一个遍历器

原生默认具备Iterator接口的数据类型如下

  • array
  • Set
  • Map
  • String
  • arguments对象
  • NodeList对象
let obj = {
  0: 'zhansan',
  1: 'zhansan1',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
}
for (let s of obj) {
  console.log(s)
}

Set结构

let s1 = new Set([1, 2, 3, 4, 5, 6, 1])
console.log(s1)

add():添加

size:长度

has():有无指定元素

delete():删除

clear():清空

Map结构

let m1 = new Map([
    ['name', 'zhan']
])

set():设置

get():获取

size:长度

has():有无指定元素

delete():删除

clear():清空

代理

// ES5代理
let obj = {

}
Object.defineProperty(obj, 'data', {
    get() {
        console.log('get')
        return box.innerHTML
    },
    set(value) {
        console.log('set', value)
        box.innerHTML = value
    }
})
console.log(obj)
// ES6代理
let obj = {

}
// 修改proxy才有效
let proxy = new Proxy(obj, {
    get(target, key) {
        console.log('get')
        return target[key]
    },
    // 当前对象,属性名,属性值
    set(target, key, value) {
        console.log('set')
        if(key === 'data') {
            box.innerHTML = value
        }
        // 修改源对象
        target[key] = value
    },
})

ES6面向对象

class Father {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
    money() {
        console.log(100)
    }
    sum() {
        console.log(this.x + this.y)
    }
}
// 继承父类
class Son extends Father {
    constructor(x, y) {
        super(x, y)// 使用父类构造函数
    }
    sum1() {
        super.sum()
    }
}
let son = new Son(1, 2)
son.money()
son.sum()
son.sum1()
;