ECMAScript 6 基础和高级
目录
- let命令和const命令
- 结构赋值
- 模板字符串
- 字符串方法
- 数值类型的扩展
- 数组的扩展运算符
- 数组新增API
- 对象的合并
- 箭头函数
- Promise 对象
- async 函数
- Class 类
- Module
let命令和const命令
let命令
- 只在 let 命令所在的代码块内有效,同时值可以被修改,不能重复声明.
const命令
- 声明一个只读的常量,常量的值就不能改变,不能重复声明.
结构赋值
数组的结构赋值
let [a, b, c] = [1, 2, 3]
console.log(a, b, c)
输出结果
1 2 3
对象的结构赋值
let { name, age } = { name: "xdd", age: 50 }
console.log(age)
输出结果
50
结果解释
{ name, age } = { name: name, age: age }
- 左侧只是精简形式, 完整的形式应该是右边
对象的结构赋值
let { name, age: num } = { name: "xdd", age: 60 }
console.log(num)
输出结果
60
模板字符串
// css
.box{
white-space: pre;
}
// html
<div id="box" class="box">
</div>
// js
let box = document.getElementById('box')
let name = 'hvgege'
box.innerHTML = `Hello
${name}!`
输出结果
Hello
hvgege!
用法
- 增强版的字符串,用反引号(`)标识
作用
- 可以当作普通字符串使用
- 可以用来定义多行字符串
- 在字符串中嵌入变量
代码解释
- 本来在反引号里面分段写的,实际体现效果却不是分段,而是空白符.
- 原因是css属性white-space, 浏览器使用默认值时,通常换行、tab、空格会被合并为一个空格.
- 将其css属性值设置为pre.
字符串方法
let a = 'app';
console.log(a.includes('a'));
console.log(a.startsWith('a'));
console.log(a.endsWith('a'));
console.log(a.repeat(3));
输出结果
true
true
false
appappapp
新增字符串方法
- includes():返回布尔值,表示是否找到了参数字符串
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
- repeat(n):方法返回一个新字符串,表示将原字符串重复n次
数值类型的扩展
- 全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变.
let a = 1.9
console.log(Number.parseInt(a))
console.log(Number.parseFloat(a))
console.log(Number.isNaN(a))
输出结果
1
1.9
false
结果分析
- parseInt()函数可解析一个字符串,并返回一个整数, 若有小数, 则去掉小数.
数组的扩展运算符
var a = [1, ...[2, 3], 4]
console.log(a)
function app(x, y, a, b) {
console.log(x+y+a+b)
}
app(...a)
输出结果
(4) [1, 2, 3, 4]
10
运算符解释
- … : 将一个数组转为用逗号分隔的参数序列
扩展运算符作用
- 主要用于函数调用和数组元素的扩充
数组新增API
Array.from(arrayLike)
var foo = {
0: 'html',
1: 'css',
2: 'js',
length: 3
}
var arr = Array.from(foo)
console.log(arr)
输出结果
(3) ["Java", "Python", "Scala"]
作用
- 将类数组对象(array-like object)转为真正的数组
类数组对象的定义
- 可以通过索引访问元素,并且拥有 length 属性, 没有数组的其他方法,例如 push , forEach , indexOf 等方法的对象.
Array.of()
var arr = Array.of(1, 2, 3)
console.log(arr)
输出结果
(3) [1, 2, 3]
作用
- 方法用于将一组值,转换为数组
arrObj.filter()
var ages = [32, 33, 16, 40];
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
var re = ages.filter(checkAdult);
console.log(re)
}
myFunction();
输出结果
(3) [32, 33, 40]
作用
- 实现过滤效果, 过滤函数的函数名作为参数.
arrObj.find()
var ages = [32, 33, 16, 40]
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
var re = ages.find(checkAdult);
console.log(re)
}
myFunction();
输出结果
32
作用
- 返回通过测试(函数内判断)的数组的第一个元素的值.
arrObj.findIndex()
var ages = [32, 33, 16, 40]
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
var re = ages.findIndex(checkAdult);
console.log(re)
}
myFunction();
输出结果
0
作用
- 返回传入一个测试条件(函数)符合条件的数组第一个元素位置.
arrObj.forEach()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>exe</title>
</head>
<body>
<button onclick="numbers.forEach(myFunction)">点我</button>
<p id="demo"></p>
</body>
<script type="text/javascript">
demoP = document.getElementById("demo");
var numbers = [4, 9, 16, 25];
function myFunction(item, index) {
console.log(index + ' ' + item)
}
</script>
</html>
点击后输出结果
0 4
1 9
2 16
3 25
作用
- 方法用于调用数组的每个元素,并将元素传递给回调函数.
arrObj.map()
// 映射, 用于处理json数组.
var data = [
{id: 1, name: '你好1'},
{id: 2, name: '你好2'},
{id: 3, name: '你好3'}
];
// ['你好1', '你好2', '你好3']
let res1 = data.map(function(item){
return `${item.id}--${item.name}`
})
console.log(res1)
输出结果
["1--你好1", "2--你好2", "3--你好3"]
作用
- 返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值.
- 映射, 用于处理json数组.
对象的合并
扩展运算符实现对象的合并
const obj = {
name: 'hgg',
age: 18,
aaa(){
console.log(9)
}
}
console.log({a: 9, ...obj})
输出结果
{a: 9, name: "hgg", age: 18, aaa: ƒ}
Object.assign(target, source1, source2)
// 对象的合并
const obj = {
name: 'hgg',
age: 18,
aaa(){
console.log(9)
}
}
let res = {}
Object.assign(res, obj, {a: 9, name: 'hvgege'})
console.log(res)
输出结果
{name: "hvgege", age: 18, aaa: ƒ, a: 9}
作用
- 将源对象(source)的所有可枚举属性,拷贝到目标对象(target), 返回值是目标对象.
代码解释
- 若合并的source属性有重复的, 则source2属性重写source1属性.
箭头函数
// 函数表达式的方式来定义箭头函数
let test = (a, b) => ({name: a, age: b})
console.log(test(1, 2))
输出结果
{name: 1, age: 2}
定义
- ES6 允许使用箭头(=>)定义函数,不再需要 function 声明.
- 如果代码块是单行表达式,不用加{}和return,如果多于一条语句写法和ES5相同.
格式
- let fn = (a, b) => a + b
参数
- 形参列表用小括号包起来,参数间用逗号分割.
- 如果只有一个参数,可以省略掉小括号.
返回值
- 如果函数调用返回json对象,需要用小括号把json对象包起来.
使用注意点
- 箭头函数不做this绑定,函数体内的this继承(就是)外层代码块的this.
Promise 对象
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(1000).then((value) => {
console.log(value);
});
1000ms后的输出结果
done
代码解释
- timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果.
- 过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数.
介绍
- Promise 是异步编程的一种解决方案,比传统的解决方案回调函数更合理和更强大,ES6 将其写进了语言标准,原生提供了Promise对象.
构造函数
- Promise 构造函数接受一个函数作为参数,该函数有两个函数类型的参数resolve和reject.
- resolve方法:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去.
- reject方法:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去.
- 实例生成以后,可以用then方法获取异步执行的结果.
promise.then(function(value) {
// success
}, function(error) {
// failure
});
setTimeout() 方法
- 用于在指定的毫秒数后调用函数或计算表达式
async 函数
async function takeLongTime() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
//reject('失败');
}, 1000);
})
}
async function test() {
try {
const res = await takeLongTime();
console.log(res);
} catch(err){
console.log(err)
}
}
test()
1000ms后的输出结果
成功
基本用法
- async函数返回一个 Promise 对象,可以使用then方法添加回调函数.
- 当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句.
代码解释
- 异步转同步, test函数中的代码同步执行, 是阻塞的.
- await 标识符必须放在 async 函数中
- takeLongTime=>不一定非得加 async, 只要返回值是 Promise 对象就行.
Class 类
class Student {
constructor(name){
this.name = name
}
say(){
console.log(this.name)
}
static speak(){ // 可能只是充当工具方法而已
console.log(this)
}
}
// 子类
class SuperStu extends Student{
constructor(name, age){
super(name)
this.age = age
}
}
const obj1 = new Student('hgg')
obj1.say()
console.log(obj1)
Student.speak()
const obj2 = new SuperStu('hvgege', 18)
console.log(obj2)
SuperStu.speak()
输出结果
hgg
Student {name: "hgg"}
class Student {
constructor(name){
this.name = name
}
say(){
console.log(this.name)
}
static speak(){ // 可能只是充当工具…
}
hvgege
SuperStu {name: "hvgege", age: 18}
class SuperStu extends Student{
constructor(name, age){
super(name)
this.age = age
}
}
代码解释
- constructor:构造函数,类的默认方法,通常用于初始化属性(支持参数),通过 new命令生成对象实例时,会自动调用该方法.
- 定义类的方法的时候,前面不需要加上function这个关键字
- 方法之间不需要逗号分隔,加了会报错
- 类的所有方法都定义在类的prototype属性上面
静态方法
- 在一个方法前,加上static关键字,不是通过实例来调用,而是直接通过类来调用.
- 如果静态方法包含this关键字,这个this指的是类,而不是实例.
继承
- 子类必须在constructor方法中调用super方法,否则新建实例时会报错.
- super方法中的形参列表和父类的constructor是一致的,用于继承属性.
- 在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错.
- 父类的静态方法,也会被子类继承.
super 关键字
- 作为函数时,super()只能用在子类的构造函数之中,用在其他地方就会报错.
- 作为对象时, 通过super调用父类的方法时,父类方法内部的this指向子类实例.
Module
基本规则和特点
- 每一个模块只加载一次,每一个JS只执行一次,如果下次再去加载同目录下同文件,直接从内存中读取.
- 一个模块就是一个单例,或者说就是一个对象.
- 每一个模块内声明的变量都是局部变量,不会污染全局作用域.
- 模块内部的变量或者方法可以通过export导出.
export 命令
- 用于规定模块对外导出的接口,必须与模块内部的变量建立一一对应关系.
import 命令
- 用于导入其他模块提供的功能,加载这个模块.
- import 命令接受一对大括号,里面指定从其他模块导入的变量名.
- 如果想为导入的变量重新取一个名字,import 命令要使用 as 关键字,将导入的变量重命名.
- import 后面的 from 指定模块文件的位置,.js后缀可以省略