ES6
let变量声明
- let变量不能重复声明
- 块级作用域
- 不存在变量提升
- 不影响作用域链
const变量声明
- 定义常量,必须赋初始值
- 一般常量用大写
- 常量的值不能修改
- 块级作用域
- 对于数组和对象的元素修改,不算对常量修改,不报错
解构赋值
- 允许按照一定模式从数组和对象中提取值,对变量进行复制
- 数组的解构
const F4 = ['a', 'b', 'c', 'd']
let [A, B, C, D] = F4
console.log(A) //A
console.log(B) //B
console.log(C) //C
console.log(D) //D
- 对象的解构
const zhao = {
name: 'Jack',
age:12,
xiaopin: function(){
console.log("hello")
}
}
let {name, age, xiaopin} = zhao;
console.log(name) //Jack
console.log(age) //12
console.log(xiaopin) //function
xiaopin(); //hello
模板字符串
- 声明 :``
- 内容中可以直接出现换行符:ul、li
- 变量拼接:
let lovest = 'Jackson';
let out = `${lovest} is my favorite!`
console.log(out) //Jackson is my favorite!
箭头函数
let fn = (a,b) =>{} //声明函数
let result = fn(1,2) //调用函数
特性
- this静态,始终指向函数声明时所在作用域下的this的值
- 不能作为构造函数去实例化对象
- 不能使用arguments
- 箭头函数的简写
** 省略小括号,当形参有且只有一个时
** 省略花括号,当代码体只有一条语句时,此时return必须省略,而且语句的执行结果就是函数的返回值
let pow = n => n * n;
参数默认值
形参初始值
let add = (a, b, c = 10) => a + b + c
let result = add(1, 2)
console.log(result) //13
与解构赋值结合
let connect = ({ name = "Jack", age, passport }) => {
console.log(name);
console.log(age);
console.log(passport);
}
connect({
age: 12,
passport: 123
}) //Jack, 12, 123
rest参数
引入rest参数,用于获取函数的实参,代替arguments
function date(...args){
console.log(args);
}
date('a', 'b', 'c'); //数组
扩展运算符
[…]将数组转换为逗号分隔的参数序列
const abc = ['a', 'b', 'c'];
function data(){
console.log(arguments);
}
data(...abc) //Arguments(3)
数组的合并
const abc = ['a', 'b', 'c'];
const efg = ['e', 'f', 'g'];
const abc_efg = [...abc, ...efg];
数组的克隆
const abc = ['a', 'b', 'c'];
const efg = [...abc];
将伪数组转为真正的数组
symbol
类似于字符串的数据类型
特点
- 值唯一,用来解决命名冲突的问题
- 不能与其他数据进行运算
- 定义的对象不能使用for in 循环遍历,可以使用Reflect.ownKeys获取对象的所有键名
创建
//创建symbol
let s1 = Symbol();
console.log(s1, typeof s1); //Symbol(), "symbol"
let s2 = Symbol('abc')
let s3 = Symbol('abc')
console.log(s2 === s3) //false
//Symbol.for创建
let s4 = Symbol.for('abc')
let s5 = Symbol.for('abc')
console.log(s4 === s5) //true
向对象添加属性和方法
let game = {
name:'俄罗斯方块',
up: function(){},
down: function(){}
};
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function(){
console.log("我可以改变形状");
}
game[methods.down] = function(){
console.log("我可以快速下降");
}
console.log(game)
let game1 = {
name:"狼人杀",
[Symbol('say')]:function(){
console.log("我可以发言");
}
[Symbol('zibao')]:function(){
console.log("我可以自爆");
}
}
内置属性
- .hasInstance:当其他对象使用instanceof运算符,判断是否为该对象的实例是,调用这个方法
- .isConcatSpreadable:布尔值,该对象用于Array.prototype.concat()时,是否可以展开
- .unscopables:该对象指定了使用with关键字时,哪些属性会被with环境排除
- .match:当执行str.match(myObject)时,如果该属性存在,调用
- .replace:当对象被str.replace(myObject)调用时,返回该方法的返回值
- .search:当对象被str.search(myObject)调用时,返回该方法的返回值
- .split:当对象被str.split(myObject)调用时,返回该方法的返回值
- .iterator:对象进行for of循环时,调用,返回该对象的默认遍历器
- .toPrimitive:该对象被转为原始类型的值时,调用,返回该对象对应的原始类型值
- .toStringTag:在该对象上调用toString方法时,返回该方法的返回值
- .species:创建衍生对象时,使用该属性
迭代器(iterator)
- 是一种接口,为各种不同的数据结构提供统一的访问机制
- for… of…保存键值
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直向后移,直到指向最后一个成员
- 没调用next方法返回一个包含value和done属性的对象
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next()); //Object(done:false, value:"唐僧")
console.log(iterator.next()); //Object(done:false, value:"孙悟空")
console.log(iterator.next()); //Object(done:false, value:"猪八戒")
console.log(iterator.next()); //Object(done:false, value:"沙僧")
console.log(iterator.next()); //Object(done:true, value:undefined)
自定义遍历
const class1 = {
name: "class1",
stus: [
'Jack',
'Bob',
'Owen',
'Sunny'
],
[Symbol.iterator]() {
//索引变量
let index = 0;
let _this = this;
return {
next: function () {
if (index < _this.stus.length) {
const result = { value: _this.stus[index], done: false };
index++;
return result;
} else {
return { value: undefined, done: true };
}
}
};
}
}
for (let v of class1) {
console.log(v);
}
生成器
特殊的函数
function * gen(){
console.log(111);
yield '一只没有耳朵'; //函数代码的分隔符
console.log(222);
yield '一只没有尾巴';
console.log(333)
yield '真奇怪';
}
let iterator = gen();
iterator.next(); //执行 111
iterator.next(); //执行 222
iterator.next(); //执行 333
for (let v of gen()){
console.log(v); //调用log和yield后面的语句
}
函数参数
gen后 整体函数可以传参
next方法也可以传入实参,作为上一个yield语句的整体返回结果
实例1
1s输出111,2s输出222,3s输出333
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
},3000);
},2000);
},1000);
改进
function one(){
setTimeout(() => {
console.log(111);
iterator.next();
},1000)
}
function two(){
setTimeout(() => {
console.log(222);
iterator.next();
},2000)
}
function three(){
setTimeout(() => {
console.log(333);
iterator.next();
},3000)
}
function * gen(){
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();
实例2
模拟获取 用户数据、订单数据、商品数据
function getUsers(){
setTimeout(()=>{
let data = '用户数据';
iterator.next(data);
},1000)
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据';
//调用next方法,将数据传入
iterator.next(data);
},1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据';
iterator.next(data);
},1000)
}
function * gen(){
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
let iterator = gen();
iterator.next();
promise
异步编程的新解决方案,语法上是一个构造函数,封装异步操作并可以获取其成功或者失败的结果
实例化promise
```cpp
const p = new Promise(function(resolve, reject){
setTimeout(function(){
let data = '数据库中数据';
resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用promise对象的then方法
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
})
Promise.prototype.then
- 返回结果是 Promise 对象,对象状态由回调函数的执行结果决定
- 如果回调函数中返回的结果是 非 promise 类型的属性,状态为成功,返回值为对象的成功的值
- 如果回调函数中返回的结果是 promise 类型的属性,状态由promise对象决定
//创建对象
const p = new Promise(resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
reject('出错啦');
}, 1000)
});
//调用then方法
const result = p.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
});
//链式调用
p.then(value=>{
}).then(value=>{
})
console.log(result);
catch方法
const p = new Promise(resolve, reject) =>{
setTimeout(() =>{
//设置p对象的状态失败,并设置失败的值
reject("出错啦!");
},1000)
});
//方法一
p.then(function(value){}, function(reason){
console.error(reason)
});
//方法二
p.catch(function(reason){
console.warn(reason);
});
Set 集合
类似于数组,成员值唯一,实现了iterator接口,可以使用扩展运算符和for…of遍历
属性和方法
- .size:元素个数
- .add:添加新的元素
- .delete:删除元素
- .has:检测是否存在
- .clear:清空
数组去重
let arr = [1,2,3,4,5,4,3,2,1];
let result = [...new Set(arr)];
console.log(result);
交集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => {
let s2 = new Set(arr2);
if(s2.has(item)){
return true;
}else{
return false;
}
})
//简化
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
并集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let union = [...new Set([...arr, ...arr2])];
console.log(union);
差集
let arr = [1,2,3,4,5,4,3,2,1];
let arr2 = [4,5,6,5,6];
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
Map
类似于对象,键值对的集合,键的范围不限于字符串,各种类型的值都可以当作键,实现了iterator接口
属性和方法
- .size:返回Map的元素个数
- .set:增加元素
- .delete:删除元素
- .get:返回键名对象的键值
- .has:检测是否包含
- .clear:清空
Class 类
定义类
类声明
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用改语法,不能使用es5
call(){}
}
let iPhone = new Phone('iphone', 7777);
构造函数继承
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
call(){
console.log('我可以打电话!');
}
}
class SmartPhone extends Phone{
//构造方法
constructor(brand, price, color, size){
super(brand, price);
this.color = color;
this.size = size;
}
photo(){
console.log('拍照');
}
playGame(){
console.log('玩游戏');
}
call(){
console.log('我可以进行视频通话');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
get和set
class Phone{
get price(){
console.log('价格属性被读取');
}
set price(newVal){
console.log('价格属性被修改了')
}
}
let s = new Phone();
s.price = 'free';
数值扩展
- Number.EPSILON:最小精度,用于浮点数运算
- 二进制 let b = 0b1010, 八进制 let o = 0o777, 十进制 let d = 100, 十六机制 let x = 0xff
- Number.isFinite:检测数值是否为有限数
- Number.isNaN:检测是否为NaN
- Number.parseInt,Number.parseFloat:字符串转整数
- Number.isInteger:判断是否为整数
- Math.trunc:将小数部分抹掉
- Math.sign:判断为正数、负数还是0,返回1、-1、0
对象方法扩展
- Object.is:判断两个值是否完全相等
console.log(Object.is(NaN, NaN)); //true
console.log(NaN === NaN); //false
- Object.assign:对象的合并
const config1 = {
host: 'localhost',
port: 3306,
name: 'root'
};
const config2 = {
host: 'atguigu',
port: 33060,
name: 'atguigu'
};
console.log(Obeject.assign(config1, config2)); //,参数重名,config2覆盖config1
- Object.setPrototypeof:设置原型对象
- Object.getPrototypeof
模块化
优点
防止命名冲突
代码复用
高维护性
功能
export:用于规定模块的对外接口
import:输入其他模块提供的功能
模块暴露数据语法export
//在js文件内暴露
//分别暴露
export var first = 'Sunny';
export var second = 'Owen';
//统一暴露
var first = 'Sunny';
var second = 'Owen';
export { first, second};
//默认暴露
export default {
first: 'Sunny';
second: 'Owen';
}
引入模块数据语法import
<script>
//html中引入m1.js
//通用导入方式
import * as m1 from "m1.js";
//解构赋值形式
import {first, second} from "m1.js";
import {default as m2} from "m1.js"; //起别名
//简便形式 针对默认暴露
import m3 from "m1.js";
<script>
babel对模块化转换
安装babel-cli babel-preset-env