ECMA6
变量声明 let
let
用let声明的变量,遇到大括号就会形成作用域,也叫做块级作用域。
用let声明的变量不能重复声明
不存在变量提升
不影响作用域链
常量声明 const
const
一定要有初始值
一般常量使用大写(规范)
块级作用域
常量值不能修改
对数组和对象的元素修改,不算做对常量的修改,不会报错
eg:const A=[1,2,3,4];
A.push(5);
解构
ES6 允许按照一定模式从数组和对象中提取值,对变量进行复制,
这被称之为解构赋值
1.中括号解构
a 数组的解构
eg: const F4=['小','刘','赵','李'];
let[xiao,liu,zhao,li]=F4;
b 赋值
eg: var[x,y,z]=[10,20,30];
var[x,[a,b],y]=[10,[20],40]
c 交换两个数
eg: var[x,y]=[10,20];
[x,y]=[y,x];
d 函数返回多个值
eg: return[结果1,结果2,结果3];
e 快速取出数组中的某一个元素
eg: var arr=[10,20,30,40,50];
var {0:first , 4:last}=arr;
alert(last);
2.大括号解构
a 对象的解构
eg: const zhao={
name:'赵本山',
age:'不详'
};
let {name,age}=zhao;
调用:zhao() zhao.age() zhao.name()
b 赋值
eg: var{name,age=20,sex} ={
age:18,
name:'钢铁侠',
sex:'男'
}
模板字符串
ES6引出的新的声明字符串的方式``反引号
1.内容中可以直接出现换行符,缩进
2.可以直接进行变量的拼接
eg: function showSelf({name,age,sex='男'}){
alert('我叫$s{name},今年${Math.max(age,20,30),${sex}性'});
}
简化对象写法
1.ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
eg:let name='刘能';
let change = function(){
console.log('xx');
}
const school={name,change}
2.在对象中添加方法
improve:function(){
console.log('improve');
}
在ES6中可以省略function 写为:
improve(){console.log('improve');
箭头函数
let 函数名=(形参)=>{代码体}
1.this是静态的,this始终指向函数声明时所在的作用域下的this的值
2.不能作为构造函数实例化对象
3.不能使用arguments变量
4.箭头函数的简写
a 省略小括号,当形参有且只有一个的时候
b 省略花括号,当代码提只有一条语句的时候,此时return必须省略,而且语句执行结果就是函数的返回值
eg:let pow=n=>n*n
5.箭头函数适合与this无关的回调,(定时器,数组方法的回调)
不适合与this有关的回调(事件回调,对象的方法)
函数参数赋初始值
1.形参初始值
function add(a,b,c=0){
return a+b+c;
}
具有默认值的参数,一般位置都要靠后
2.与解构赋值结合,获取实参
原始方法: function调用函数获取实参,代码冗余
function connect(options){
let host=options.host;
let b=options.b;
let c=options.c;
}
connect({
host:'xxx',
b:'xxx',
c:'xxx'
})
改良:可以直接通过形参得到实参的值,简化了代码
function connect({host,b,c}){
console.log(host);
console.log(b);
console.log(c);
}
rest参数
ES6引入了rest参数,用于获取函数的实参,来代替arguments,结果返回的是一个数组
...形参名 :用于获取函数的实参
eg:function date(...args){
console.log(args);
}
date('111','222','333');
扩展运算符及其应用
ES6扩展运算符(…)
能将数组转换为逗号分隔的参数序列
eg:
const tfboys =['易烊千玺','王源','王俊凯'];
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys); //等同于chunwan('易烊千玺','王源','王俊凯')
扩展运算符的应用
1.数组的合并
const arr1=[1,1,1,1,1];
const arr2=[2,2,2,2,2];
const A = [...arr1,...arr2];
2.数组的克隆
const a=['e','g','m'];
const A=[...a]; //浅拷贝
3.将为数组转成真正的数组
const Divs = document.querySelectorAll('div');
const Divarr =[...Divs];
symbol
ES6引入了一种新的原始数据类型symbol,表示独一无二的值
1.值是唯一的,解决命名冲突问题
2.symbol值不能与其他类型的值进行运算,自己和自己也不行
3.不能用for...in循环遍历,但可以使用reflect.ownkeys来索取对象的键名
4.创建symbol
let s=symbol();
let s2=symbol('四叶草'); //函数 这样创建出来的symbol写多个,就是多个
let s3=symbol('四叶草');
s2 == s3; //false
let s4=symbol.for('四叶草'); //函数字符串,写多个相同会看作一个来对待
symbol的应用
给对象添加属性和方法
demo1.给原有对象添加方法up down
let game={} //原来的对象,里面不知道是否有原有的up down
let methods ={
up:symbol(),
down:symbol()
};
game[methods.up]=function(){
console.log('up');
}
game[methods.down]=function(){
console.log('down');
}
demo2.
let youxi={
name:"狼人杀",
[symbol('say')]:function(){
console.log("我可以发言")
},
[symbol('zibao')]:function(){
console.log("自爆")
}
}
symbol内置值是symbol的属性,而他们这个整体有作为对象的属性去设置
迭代器
迭代器(iterator)是一种接口,为各种不同的数据提供统一的访问机制。
任何数据结构子要部署了iterator接口,就可以完成遍历操作
(iterator接口,就是对象中的一个属性,名字叫做symbol.inerator)
for...in保存的是键名
for...of保存的是键值
迭代器的工作原理
1.创建一个指针对象,指向当前数据结构的起始位置
2.第一次调用对象的next方法,指针自动指向数据结构的第一个成员
3.接下来不断调用next,指针一直向后移动,直到最后一个成员
4.每调用next方法返回一个包含value和done属性的对象, done返回是否完成遍历,返回一个Boolean值
自定义遍历数组
const banji ={
name:"终极一班",
stus:[
"xiaoliu",
"xiaozhang",
"xiaotan",
"xiaoli"
]
[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;
}lese{
return{value:undifined,down:true};
}
}
}
}
}
生成器
生成器(其实就是一个特殊的函数)可以进行异步编程
1.声明
function * 函数名(){}
2.调用
let a =函数名();
a.next();
3.生成器中可以写yield,yield可以看作是代码的分隔符,把代码分割成几块
eg:
function * gen(){
console.log('111');
yield'一一一';
console.log('222');
yield'二二二';
}
let iterator = gen();
iterator.next; //输出111
iterator.next; //输出222
4.生成器的函数参数
a.let a=函数名(这里可以传入实参)
b.next方法可以传入实参,传入的实参会作为上一个yiled整体的返回结果
5.异步编程
demo:1秒后台控制输出111,两秒后输出222,三秒后输出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 iteration=gen();
iteration.next();
promise
promise是ES6引入的异步编程的新的解决方案,语法上promise是一个构造函数,用来封装
异步操作并可以获取其成功或者失败的结果,解决回调地狱问题
1.实例化promise对象
const P=new promise(function(resolve,reject){异步程序});
异步程序中可以读取一些数据,数据读取成功调用resolve(变量命),
读取失败调用reject(存储数据的变量命),之后调用promise对象的
then方法,成功执行value,失败则执行reason
p.then(function(value){
读取成功的代码
},function(reason){
读取失败的代码
})
2.读取文件
1> 引入fs模块 const fs=require('fs');
2>调用方法读取文件
fs.readFile('路径',(err,data)=>{
if(err) throw err; //如果失败,则抛出错误
console.log(data.toString()); //如果没有出错,则输出内容
})
3.使用promise封装
const P=new promise(function(resolve,reject){
fs.readFile("./resources/weixue.md",(err,data)=>{
if(err) reject(err);
resolve(data);
});
});
P.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取失败");
});