(一)let: 声明变量
1.没有声明提前的概念
2.不能在同一作用域重复声明同一个变量
3.块级作用域{}
1 let a = 20; 2 function show(){ 3 let a = 20; 4 } 5 console.log(a) 6 报错:Identifier 'a' has already 7 been declared 变量a已经被声明
案例:输出按钮索引值
1 //ES5方法 2 //相当于var i; 3 for(var i=0;i<btns.length;i++){ 4 btn[i].idx = i; 5 btns[i].onclick = function(){ 6 setTimeout(function(){ 7 console.log(this.idx); 8 }.bind(this),2000) 9 } 10 } 11 //ES6方法: 12 for(let i=0;i<btns.length;i++){ 13 //相当于let i; 14 btns[i].onclick = function(){ 15 setTimeout(function(){ 16 console.log(i); 17 },2000) 18 } 19 } 20 //考察知识点: 21 //1.变量的访问规则 22 //2.let的块级作用域{}
(二)const:声明常量
备注:const常用于引用第三方库的声明
1、变量声明不会提前
2、块级作用域
3、const不允许相同作用域内多次声明同一变量
4、声明后无法修改值
演示:(常量无法修改,所以有不成文规定,用大写字母表示)
const MY_NAME = 'laoxie';
// 报错:无法修改常量的值 ==> Assignment to constant variable
MY_NAME = 'LEMONE';
//演示:PI、Number内置的一些常量属性
二、解构
(一)概念
声明变量时,从数组和对象中提取值,对变量进行赋值,这种方式叫做解构
(二)、数组解构
1、基本解构:[变量名,变量名] = 数组
1 var[a,b,c] = [10,20,30]; 2 console.log(a,b); //var a=10,b=20 ,c=30;
2、...表示获取剩余参数
1 var[a,...b] = [10,20,30] 2 console.log(a,b); //var a=10,b=[20,30];
3、解构失败
(1)变量的长度大于数组的长度,出现解构失败,得到undefined
1 var[a,b,c,d] = [10,20,30]; 2 console.log(a,b,c,d);//d解构失败:数组arr中无对应索引值
(1)解构右侧不是数组,报错。
1 var [a] = 1;//a解构失败,对应的右边不是数组,无法解构
4.指定默认值:当变量解构失败的话,拿到默认值
(三)、对象解构
1、基本解构:{变量名1,变量名2} = 对象
*要求变量名与对象的属性名一致
1 var obj = {name:"lemon",age:18}; 2 var {name,age} = obj; // var name="lemon",age=18;
2、解构失败,得到undefined
1 var {username,age} = obj;//username解构失败,变量必须与对象属性名相同,否则为undefined
3.如果变量名与属性名不相同,则必须写成以下格式才能取到值: {属性名:变量名} =对象
1 var {name:username,age} = obj; 2 //声明的变量为username,解构obj中的name属性 3 //相当于:var username="lemon",age=18;
4.指定默认值:当变量解构失败的话,拿到默认值
1 var {a=10} = {};//当a解构失败的话,拿到默认值
备注:不仅解构时可以传递默认值,基本数据类型作为形参时也可以传递默认值,也可以通过...变量名获取剩余的参数。
案例:字符串模板
备注:只需在最前面加反引号,其他的位置都可以不用,用$值链接得到的属性值
1 var output = document.getElementById("output"); 2 var arr = [{ 3 id : '001', //item.id 4 name : "laotian", 5 age : 38, 6 gender : "女", 7 hobby : "健身教练" 8 },{ 9 id : '002', 10 name : "lemon", 11 age : 17, 12 gender : "女", 13 hobby : "开车" 14 },{ 15 id : '003', 16 name : "mengzhu", 17 age : 18, 18 gender : "女", 19 hobby : "瑜伽" 20 }]; 21 output.innerHTML = arr.map(function(item){ 22 var {id,name,age,gender,hobby} = item; 23 return `<li uid="${id}"> 24 <h4>${name}</h4> 25 <p>年龄:${age}</p> 26 <p>性别:${gender}</p> 27 <p>爱好:${hobby}</p> 28 </li>`; 29 }).join("");
三、字符串扩展
(一)字符串方法(了解)
1、includes
判断是否包含某个字符,返回布尔值
1 'html5'.includes('html');//true
2、startsWith/endsWith
1 是否以某一字符或某一字符串开头/结尾 2 let str='google'; 3 str.startsWith('goo'); //true 4 str.endsWith('e'); //true
3、repeat(n)
得到字符串重复n次后的结果,n可以为小数,但不能为负数
(二)字符串模板(重点)
1、使用反引号``表示,使用${变量}往字符串插入变量(美观、方便)
2、格式:${变量|函数}
1 var fruit = "apple"; 2 console.log(`一天一个${fruit},医生远离我`);
四、函数扩展(重点)
(一)箭头函数
1、格式:标识符=>表达式
2、省略了function、return关键字、圆括号、花括号
3、函数内只有一句return代码,可省略{}及return。
*没有参数或存在多个参数
*只有一个参数,还可以省略()
1 var test = function(x){return x+2;} // 箭头函数: var test = x=>x+2;
(2)零个参数用 () 表示
1 var sum = function(){return 10 + 10;} // 箭头函数: var sum = () => 10+10;
4、函数内有多句代码,不要省略{}、return,用代码块括起来
1 * 箭头函数=>后面紧跟着的{}代表的是代码块 2 //ES6中的规则是,紧随箭头的{}被解析为块的开始,而不是对象的开始 3 4 // ES5 5 6 btn.onclick = function (e) { 7 e = e || window.event; 8 var keCode = e.which || e.keyCode; 9 console.log(keyCode); 10 }; 11 12 // ES6 13 btn.onclick = e=>{ 14 e = e || window.event; 15 var keyCode = e.which || e.keyCode; 16 console.log(keyCode); 17 };
5、当使用箭头函数return值为一个普通对象时,需要将对象包裹在小括号里
1 //传统写法 2 var createPerson = function(){ 3 return {name:'laoxie',age:18}; 4 } 5 // ES6 6 var createPerson = ()=>{name:'laoxie',age:18}; // 这样写会报Bug! 7 var createPerson = ()=>({name:'laoxie',age:18});
6、箭头函数自身没有this
箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
1 document.addEventListener("DOMContentLoaded", function(){ 2 var btn = document.querySelectorAll(".btn"); 3 //ES5 4 for(var i=0;i<btn.length;i++){ 5 btn[i].onclick = function(){ 6 setTimeout(function(){ 7 console.log(this.value); 8 }.bind(this), 1000) 9 } 10 } 11 12 //ES6 13 for(var i=0;i<btn.length;i++){ 14 btn[i].onclick = function(){ 15 setTimeout(() => { 16 console.log(this.value); 17 18 }, 1000) 19 } 20 } 21 })
(二)生成器函数
1、function* 函数名(){}:执行生成器函数会返回一个suspended的对象
2、 yield val; 暂停代码的执行
3、next():得到一个对象
4、return:终止函数
(1)value:暂停时返回的值(yield)
(2)done:表示函数是否执行完毕
1 function* sum(x){ 2 console.log(1); 3 yield 50; 4 console.log(2); 5 yield 100; 6 console.log(3); 7 // return 150; 8 console.log('end'); 9 } 10 var res = sum();//得到一个状态为suspended的对象{next()} 11 // res.next();//得到一个对象:{value:xx,done:false} 12 console.log(res);
五、set集合
定义:
类似于数组,但是成员的值都是唯一的,可自动去重
生成set集合:var s = new Set()
(1)去重的前提是两个值恒等于
(2)利用set集合去重数组
*Array.from(set集合)将set集合或者类数组转成数组
2、Array.from(items) 去重
var arr = [1, 2, 3, 4, 5, 5, 5, 5];
let items = new Set(arr);
//去重后将set集合重新转成数组
arr = Array.from(items);
(一)set的方法
1、add(value)==> 添加某个值
添加某个值,返回Set结构本身
1 案例: 2 var s = new Set(); 3 s.add("10"); 4 s.add(10); 5 s.add({name:"lemon"}); 6 s.add({name:"lemon"}); 7 console.log(s); 8 备注:两个对象,健和值虽然一样,但是它们是不相等的,因为它们地址不一样
2、delete(value)==> 删除某个值
删除某个值,返回一个布尔值,表示删除是否成功。
3、has(value):==>判断set值
返回一个布尔值,表示Set集合中是否存在该值。
3、clear():清除所有成员,没有返回值
(二)遍历set集合
1、forEach()
2、 for(var item of s){item代表集合中的每一项值}
1 例: 2 var s = new Set(); 3 s.add("10"); 4 s.add(10); 5 s.add({name:"lemon"}); 6 s.add({name:"lemon"}); 7 console.log(s); 8 遍历方法: 9 ES5方法: 10 s.forEach(function(item){ 11 console.log(item); 12 }) 13 ES6方法: 14 for(var item of s){ 15 console.log(item); 16 } 17
(三)for...of
1、这是最简洁、最直接的遍历数组元素的语法
2、for…of跟for-in的区别很明显,就是直接取值,而不再取下标了
3、与forEach()不同的是,它可以正确响应break、continue和return语句
1 var arr = [1,3,6]; 2 for(var item of arr){ 3 if(item == 3){ 4 break;//循环语句、for...of 5 } 6 console.log(item); 7 }
只要有[迭代器Symbol(Symbol.iterator) ]就可以用for...of遍历
Array
DOM
Set/Map集合
String
不支持普通对象
六、对象的扩展(重点)
(一)对象合并方法
1、对象的合并 Object.assign(obj1,obj2)
将多个对象合并成obj1,并返回obj1
1 var obj1 = {a:1}; 2 var newObj1 = Object.assign(obj1,{b:2}); 3 //1.合并对象到obj1,所以obj1 = {a:1,b:2} 4 //2.返回obj1,传递给newObj1,所以newObj1 = {a:1,b:2} 5 6 var newObj2 = Object.assign(obj1,{b:2},{b:4,c:3}); 7 //若存在相同属性,后面的覆盖前面的。//newObj=obj1={a:1,b:4,c:3}
(二) 对象的传递与复制
1、var obj2 = obj1;传递是地址
所以一旦改变其中一个对象的值,另外一个会受影响
1 var obj = { 2 name:"laoxie", 3 hobby:['大保健','money'] 4 } 5 1.对象的传递: 6 var newObj = obj; //此时修改obj的任意属性,也会同时影响newObj
2、浅复制(对于引用类型,只拷贝地址)
(1)for...in 遍历对象中的键,传递给另外个对象
(2)var new = Object.assign({},obj);
2.对象的复制 (1)for...in遍历复制
1 for(var key in obj){ 2 newObj2[key] = obj[key]; 3 }
(2)利用assign()
1 var newObj3 = Object.assign({},obj);
3、深复制
-
将引用数据类型转成基本数据类型进行传递
-
再转成引用数据类型
这是分开写法:
1 var str = JSON.stringify(obj1); 2 var obj3 = JSON.parse(str);
这是结合写法:
1 var new = JSON.parse(JSON.stringify(obj1))
(三)对象简写
ES6允许在对象之中直接写变量
1.属性直接写变量名:变量名作为属性名,变量值作为属性值。
1 var myName = 'laoxie'; 2 var obj = {myName};//等效于var obj = {myName:'laoxie'}。变量名作为属性名,变量值作为属性值。
2.属性为[变量名],代表变量值为属性名
1 var obj = { 2 [myName]:18 //等效于 laoxie:18 3 }
-
方法简写:方法名(){}
1 var obj = { 2 coding(){} //等效于 coding:function(){} 3 }
(四)Map集合:它能让所有类型的数据作为键
(一) 常用方法:
1、set(key, value) ==> 设置
2、get(key) ==> 获取
3、has(key) ==> 判断值
4、delete(key) ==> 删除某个键
5、 clear() ==> 清楚所有成员,没有返回值
1 let map = new Map(); 2 3 //设置: 4 map.set('name','laoxie'); 5 map.set(6,666); 6 // 把数组作为键 7 var arr = [10,20,30]; 8 map.set(arr,'数组'); 9 10 //获取: 11 map.get(arr); //[10,20,30]
(二) 遍历方法
1、keys() 获取所有键(类数组),可以用Array.from()转成数组
2、values() 获取所有值,可以用Array.from()转成数组
3、entries() 获取所有键值对,可以用Array.from()转成数组
4、for(var item of map){item存放map集合的每一项键值对,item为一个数组,item[0]代表键,item[1]代表值}
1 配合解构:获取for(var [key,val] of m){key代表map集合的每个键,val代表每个值} 2 3 for(var item of map){ 4 console.log(item); //每个item得到的都是一个数组,索引0为键,索引1为值 5 } 6 //解构写法: 7 for(var [key,value] of map){ 8 console.log(key,value); 9 }
七、Symbol数据类型
1、表示独一无二的值,一旦创建后就不可更改2、接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了标识和区分3、 symbol不可以与其他类型的值进行运算,会报错4、 Symbol.for() 第一次就是创建symbol,会先查找当前Symbol是否存在
1 // 存在:则引用,不存在:则创建登记 2 var s11 = Symbol.for('laoxie');//创建一个Symbol 3 var s12 = Symbol.for('laoxie');//引用一个Symbol 4 //注意:直接使用Symbol()创建的Symbol值的键不会被登记,所以也就获取不到 5 6 7 // 没有参数的情况 8 var s1 = Symbol(); 9 var s2 = Symbol(); 10 s1 === s2 // false 11 12 //Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了标识和区分,对调式非常有用 13 // 有参数的情况 14 var s1 = Symbol("foo"); 15 var s2 = Symbol("foo"); 16 s1 === s2 // false 17 18 //Symbol值不能与其他类型的值进行运算
(一)symbol的用途
1、给对象创建私有属性
2、给现有的对象添加属性,可能会产生命名冲突,Symbol的出现解决这个问题
1 var attr = Symbol(); 2 3 // 第一种写法,不用加引号 4 var a = {}; 5 a[attr] = 'Nani'; 6 7 // 第二种写法(注意加方括号,否则回被当作普通属性) 8 var a = { 9 [attr]: 'Nani'; 10 }; 11 12 // 以上写法都得到同样结果 13 a[attr] // "Nani"