ES6
变量声明
let: 声明变量
1)变量声明不会提前
2)let不允许相同作用域内多次声明同一变量
3)块级作用域 {}
演示:let声明变量的特点
let num = 666;//报错,不允许在同一作用域声明已存在的变量,其次变量声明不会提前
var num = 100;
var num = 10;
console.log(num);
案例:输出按钮索引值
//ES5方法
//相当于var i;
for(var i=0;i<btns.length;i++){
btn[i].idx = i;
btns[i].onclick = function(){
setTimeout(function(){
console.log(this.idx);
}.bind(this),2000)
}
}
//ES6方法:
for(let i=0;i<btns.length;i++){
//相当于let i;
btns[i].onclick = function(){
setTimeout(function(){
console.log(i);
},2000)
}
}
//考察知识点:
//1.变量的访问规则
//2.let的块级作用域{}
const:声明常量
1)变量声明不会提前
2)块级作用域
3)const不允许相同作用域内多次声明同一变量
4)声明后无法修改值
演示:
const MY_NAME = 'laoxie';
// 报错:无法修改常量的值
MY_NAME = 'LEMONE';
//演示:PI、Number内置的一些常量属性
const常用于引用第三方库的声明
解构
声明变量时,从数组和对象中提取值,对变量进行赋值,这被叫做“解构” 。
数组解构
var [a,b] = [1,2];
console.log(a,b);//var a=1,b=2;
var [a,...b] = [1,2,3,4]; //...表示获取剩余参数
console.log(a,b); //var a=1,b=[2,3,4];
//(1)解构失败,得到undefined
var[a,b,c,d] = [10,20,30];
console.log(a,b,c,d);//d解构失败:数组arr中无对应索引值
var [a] = 1;//a解构失败,对应的右边不是数组,无法解构
//(2)指定默认值:
var [a=true]= 1; //当a解构失败的话,拿到默认值
对象解构
var obj = {name:"lemon",age:18};
var {name,age} = obj; // var name="lemon",age=18;
//(1)解构失败,得到undefined
var {username,age} = obj;//username解构失败,变量必须与对象属性名相同,否则为undefined
//(2)如果变量名与属性名不相同,则必须写成以下格式才能取到值
var {name:username,age} = obj; //声明的变量为username,解构obj中的name属性
//相当于:var username="lemon",age=18;
//(3)指定默认值:
var {a=10} = {};//当a解构失败的话,拿到默认值
应用
-
交换变量值
var [x,y] = [y,x];
var x = 10; var y = 20; var[x,y] = [y,x]; //相当于var x = 20;var y = 10;
-
函数返回多个值
//数组: function example(){ return [1,2,3] } var [x,y,z] = example(); //对象: function example(){ return {name:"lemon",age:18}; } var {name,age} = example();
-
定义函数形参(重点)
//数组: function test([x,y,z]){ //相当于 var [x,y,z] = [1,2,3]; } test([1,2,3]); //对象: function test({name,age}){ //相当于 var {name,age} = {name:"lemon",age:18}; } test({name:"lemon",age:18}); //常规操作:参数可以设置默认值 fuction test({x=0,y=0,z=0}){ //相当于var {x=0,y=0,z=0} = {x:10} //为避免没有实参值传入,给形参默认值 } test({x:10}); //扩展:若形参是基本数据类型,函数也可以对形参进行设置默认值的操作。 var func1 = function(x=1,y=2){return x+y}; func1(); // 得到 3 //同样,也可以用...表示获取剩余参数 var func2 = (x, ...args) => { console.log(args) }; func2(1,2,3); // 输出 [2,3]
字符串扩展
字符串方法
includes
判断是否包含某个字符,返回布尔值
'html5'.includes('html');//true
startsWith/endsWith
是否以某一字符或某一字符串开头/结尾
let str='google';
str.startsWith('goo'); //true
str.endsWith('e'); //true
repeat(n)
得到字符串重复n次后的结果,n可以为小数,但不能为负数
'laoxie'.repeat(2);//laoxielaoxie
字符串模板template string (重点)
- 使用反引号``表示,你可以通过一种更加美观、更加方便的方式向字符串中插入变量
- 格式:${变量|函数},
`你好,我的名字叫${username},接下来是我的自我介绍:${introduce()}`
模板字符串中所有的空格、换行、缩进,都会原样输出在生成的字符串中。
案例:根据数据生成一个商品列表
箭头函数arrow function(重点)
基本操作
-
格式:标识符=>表达式
-
省略了function、return关键字、圆括号、花括号
//(一)函数内只有一句return代码,可省略{}及return。
// 1. 零个参数用 () 表示 var sum = function(){return 10 + 10;} // 箭头函数: var sum = () => 10+10; // 2. 函数只有一个参数(可省略括号) var test = function(x){return x+2;} // 箭头函数: var test = x=>x+2; // 3. 函数有多个参数,用(参数)表示 var test = function(x,y){return x+y;} // 箭头函数: var test =(x,y)=>x+y; //(二)函数中包含多行代码时用代码块括起来 //ES6中的规则是,紧随箭头的{}被解析为块的开始,而不是对象的开始 // ES5 btn.onclick = function (e) { e = e || window.event; var keCode = e.which || e.keyCode; console.log(keyCode); }; // ES6 btn.onclick = e=>{ e = e || window.event; var keyCode = e.which || e.keyCode; console.log(keyCode); }; //(三)当使用箭头函数返回一个普通对象时,需要将对象包裹在小括号里 //传统写法 var createPerson = function(){ return {name:'laoxie',age:18}; } // ES6 var createPerson = ()=>{name:'laoxie',age:18}; // 这样写会报Bug! var createPerson = ()=>({name:'laoxie',age:18});
箭头函数中的this值
箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
生成器函数 Generators
-
function和函数名之间有一个*号
-
yield :暂停代码执行
-
return:终止函数
-
next() : 执行后得到一个对象,有两个属性如下:
- value:暂停时返回的值(yield)
- done:表示函数是否执行完毕
function* sum(x){ console.log(1); yield 50; console.log(2); yield 100; console.log(3); // return 150; console.log('end'); } var res = sum();//得到一个状态为suspended的对象{next()} // res.next();//得到一个对象:{value:xx,done:false} console.log(res);
Set集合
- Set集合,类似于数组,但是成员的值都是唯一的,可自动去重。
- 去重的前提是两个值恒等于。
set的方法
- add(value):添加某个值,返回Set结构本身。
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
- has(value):返回一个布尔值,表示Set集合中是否存在该值。
- clear():清除所有成员,没有返回值。
let imgs = new Set(); //创建一个set集合
imgs.add(1);
imgs.add(1);
imgs.add(5);
imgs.add("5");
imgs.add({name:"lemon"});
imgs.add({name:"lemon"});
//打印的结果: 1 5 '5' {name:"lemon"} {name:"lemon"}
利用set去重数组
var arr = [1, 2, 3, 4, 5, 5, 5, 5];
let items = new Set(arr);
//去重后将set集合重新转成数组
arr = Array.from(items);
遍历set集合
- forEach()
- for…of
set.forEach((item,idx)=>{
console.log(item,idx);
})
var imgs = new Set(['a','b','c']); //根据KEY遍历
for(let item of imgs){
console.log(item);
}
for…of
- 这是最简洁、最直接的遍历数组元素的语法
- for…of跟for-in的区别很明显,就是直接取值,而不再取下标了
- 与forEach()不同的是,它可以正确响应break、continue和return语句
var arr = [10,12,18,30];
for (var value of arr) {
console.log(value);
}
只要有[迭代器Symbol(Symbol.iterator) ]就可以用for…of遍历
- Array
- DOM
- Set/Map集合
- String
- 不支持普通对象
对象扩展(重点)
对象合并方法
Object.assign(obj1,obj2,…objN); 合并对象到obj1,返回obj1
var obj1 = {a:1};
var newObj1 = Object.assign(obj1,{b:2});
//1.合并对象到obj1,所以obj1 = {a:1,b:2}
//2.返回obj1,传递给newObj1,所以newObj1 = {a:1,b:2}
var newObj2 = Object.assign(obj1,{b:2},{b:4,c:3});
//若存在相同属性,后面的覆盖前面的。//newObj=obj1={a:1,b:4,c:3}
扩展:对象的传递与复制
var obj = {
name:"laoxie",
hobby:['大保健','money']
}
//1.对象的传递:
var newObj = obj; //此时修改obj的任意属性,也会同时影响newObj
//2.对象的复制
//(1)for...in遍历复制
for(var key in obj){
newObj2[key] = obj[key];
}
//(2)利用assign()
var newObj3 = Object.assign({},obj);
//注意:以上两种复制方式,都只支持浅拷贝(对于引用类型,只拷贝引用)
obj.hobby.push('羽毛球');//此时也会影响newObj2与newObj3
//(3)深拷贝
var newObj3 = JSON.parse(JSON.stringify(person));
对象简写
ES6允许在对象之中直接写变量,如
//1. 属性简写
var myName = 'laoxie';
var obj = {myName};//等效于var obj = {myName:'laoxie'}。变量名作为属性名,变量值作为属性值。
//2.使用变量值作为属性名
var obj = {
[myName]:18 //等效于 laoxie:18
}
//3.方法简写
var obj = {
coding(){} //等效于 coding:function(){}
}
Map集合
js对象(Object)只能用字符串当作键(属性名)。这让它的使用有了很大的限制。所以ES6推出了一种类似于对象的数据集合:Map集合,它能让所有类型的数据作为键
常用方法
- 设置set(key, value)
- 获取get(key)
- has(key)
- delete(key)
- clear()
//创建:
let map = new Map();
//设置:
map.set('name','laoxie');
map.set(6,666);
// 把数组作为键
var arr = [10,20,30];
map.set(arr,'数组');
//获取:
map.get(arr); //[10,20,30]
遍历方法
- keys() 获取所有键(类数组),可以用Array.from()转成数组
- values() 获取所有值,可以用Array.from()转成数组
- entries() 获取所有键值对,可以用Array.from()转成数组
- 循环遍历,配合解构赋值 for…of
for(var item of map){
console.log(item); //每个item得到的都是一个数组,索引0为键,索引1为值
}
//解构写法:
for(var [key,value] of map){
console.log(key,value);
}
Symbol数据类型
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,一旦创建后就不可更改,是一种类似于字符串的数据类型,但Symbol 值不能与其他类型的值进行运算,否则报错。
symbol的创建
// 没有参数的情况
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
//Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了标识和区分,对调式非常有用
// 有参数的情况
var s1 = Symbol("foo");
var s2 = Symbol("foo");
s1 === s2 // false
//Symbol值不能与其他类型的值进行运算
symbol的用途
- 给对象创建私有属性
- 给现有的对象添加属性,可能会产生命名冲突,Symbol的出现解决这个问题
var attr = Symbol();
// 第一种写法,不用加引号
var a = {};
a[attr] = 'Nani';
// 第二种写法(注意加方括号,否则回被当作普通属性)
var a = {
[attr]: 'Nani';
};
// 以上写法都得到同样结果
a[attr] // "Nani"
Symbol.for() 登记symbol,会先查找当前Symbol是否存在
// 存在:则引用,不存在:则创建登记
var s11 = Symbol.for('laoxie');//创建一个Symbol
var s12 = Symbol.for('laoxie');//引用一个Symbol
//注意:直接使用Symbol()创建的Symbol值的键不会被登记,所以也就获取不到