一、let和const
1、let
(1)let所声明的变量,只在命令所在的代码块内有效; (2)let所声明的变量,在域解析的时候不会被提升,即:声明变量前,不可被调用; (3)let不允许在同一个作用域下声明已经存在的变量; (4)在for循环语句之内是一个父作用域;在循环体内是一个子作用域;二者相互分离,互不干涉。2、const
(1)const所声明的变量,只在命令所在的代码块内有效; (2)const所声明的变量,在域解析的时候不会被提升,即:声明变量前,不可被调用; (3)const不允许在同一个作用域下声明已经存在的变量; (4)const声明的变量必须赋值; (5)const声明的常量存储简单的数据类型的时候不可改变其值;如果存储的是对象,那么引用不可被改变,至于对象里面的数据如何变化,是没有关系的。学习网址:
二、变量的解构赋值
1、数组的结构赋值:变量的取值由位置决定
2、对象的解构赋值:变量名与属性名一一对应,次序不重要 3、基本类型解构赋值:null/undefined不能进行解构赋值学习网址:
三、数据结构Set
1、集合的概念
集合是由一组无序且唯一的项组成,类似于数组,但没有重复的值。 特点:key和value相同,没有重复的value。 2、如何创建一个Set:const s = new Set([1,2,3]);
3、Set的属性:s.size = 3;
4、Set类的方法 (1)add(value)添加一个数据,返回set结构本身;s.add(“value”)
(2)delete(value)删除指定数据,返回一个布尔值,表示删除是否成功; (3)has(value)判断该值是否为Set成员,返回一个布尔值; (4)clear()清除所有数据,没有返回值; (5)keys()返回键名的遍历器; (6)values()返回键值的遍历器; (7)Entries()返回键值对的遍历器; (8)ForEach()使用回调函数遍历每个成员:s.forEach(function(value,key,set){ });
学习网址:
5、set不允许有重复数据,如何利用set为数组进行去重?
var array = [1,2,3,4,2,2,5];var set = new Set(array);array = Array.from(set);//注:Array.from()方法从一个类似数组或可迭代的对象中创建一个新的数组实例。
学习网址: 为数组去重:
四、数据结构Map(字典类型)
1、字典:是用来存储不重复key的hash结构;不同于集合(set)的是,字典使用的是[键,值]的形式来储存数据的。
2、如何创建一个MapConst map = new Map([ [‘a’:1], [‘b’:2]]);
3、Map类的属性map.size = 2;
set(key,value)
:设置键名key对应的键值为value,然后返回整个Map结构,如果key已经有值,则键值会被更新,否则就新生成改键。 map.set(“key”,”value”).set(“key2”,”value2”).set(“key”,”value3”);//注:key对应的键值最终为value3
(2)get(key)读取key对应的键值,如果找不到key,返回undefinded
map.get(“key”);=====>value3
(3)delete(key) 删除某个键,返回true。如果删除失败,返回false
map.delete(“key”);=====>true
(4)has(key) 方法返回一个布尔值,表示某个键是否存在当前Map对象之中
map.has(“key2”);=====>truemap.has(“key”);=====>false
(5)clear() 清除所有数据,没有返回值;
(6)keys()返回键名的遍历器; (7)values()返回键值的遍历器; (8)Entries()返回键值对的遍历器; (9)ForEach()使用回调函数遍历每个成员:map.forEach(function(value,key,map){ });
//注:map属于地址存值,里面的key的排列顺序是按照添加顺序进行排列的。
学习网址:
五、iterator和for-of循环
1、iterator是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署iterator接口,就可以完成遍历操作,而且这种遍历操作是依次处理该数据结构的所有成员。
2、iterator遍历器的作用: (1)为各种数据结构,提供一个统一的、简便的访问接口; (2)使得数据结构的成员能够按某种次序排列; (3)ES6新增了遍历命令for..of循环,iterator接口主要供for..of消费。 3、手写iterator接口Const arr = [1,2,3];Function iterator(arr){ let index = 0; return{ next:function(){ return index < arr.length ? {value : arr[index++], done : false} : {value : undefined, done : true}; } }}Const it = iterator(arr);Console.log(it.next());====>1Console.log(it.next());====>2Console.log(it.next());====>3Console.log(it.next());====>undefined
学习网址:
4、凡是具备symbol.iterator
属性的数据结构都具备iterator接口
六、class的基本使用
1、原型链
Class miaov{ Constructor(a,b){ This.a = a; This.b = b; Return this; } Print(){ Console.log(this.a + ‘ ’ + this.b ); }};Const miaov = new miaov(“hello”,”world”).print();
2、miaov中的constructor方法是构造方法,this关键字则代表实例对象,也就是说,ES5的构造函数miaov,对应ES6的miaov这个类的构造方法;
3、miaov这个类除了构造方法,还定义了一个print方法:注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错; 4、构造函数的prototype属性,在ES6的“类”上面继续存在,而且类的所有方法都定义在类的prototype属性上面; 5、定义在“类”中的方法都是不可以枚举的。Console.log(object.keys(miaov.prototype));
6、constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法,一个类必须有constructor方法,如果没有显示定义,一个空的constructor方法会被默认添加;
生成类的实例对象的写法,与ES5完全一样,也是使用new命令。如果忘记加上new,像函数那样调用class,将会报错;七、class的继承相关知识(canvas画布实现小球自由落体运动)
1、extends、static、super 通过extends继承父类,通过super()传递参数八、Symbol数据类型
1、什么是Symbol?
(1)Symbol表示独一无二的值,它是js中的第七种数据类型 (2)js数据类型: 基本数据类型:Symbol、string字符串、number数字、boolean布尔、array数组、Null、Undefined
引用数据类型:object对象
2、创建symbol数据类型值 Let sl = Symbol();
//注:Symbol函数前不能使用new,否则会报错,原因在于Symbol是一个原始类型的值,不是对象。
3、Symbol参数
Let s2 = Symbol(“a”); //a就是Symbol的参数//Symbol函数读取一个字符串作为参数,表示对Symbol的描述,主要是为了在控制台显示,或者转为字符串的时候,比较容易区分。
4、Symbol数据类型的转换
String(Symbol(“miaov”)); //转换成字符串Symbol(“leo”).toString(); //转换成字符串!!Symbol(); //true值//注:Symbol不能使用任何运算符进行运算
5、作为对象的属性名
//注:不能被for...in...循环遍历
九、内置对象的扩展
1、字符串的扩展
模板字符串:(1)字符串放在反引号当中(tab上的为反引号)(2) ${ ‘首页’ } (3)支持三目运算
2、repeat
Let str1 = ‘a’;Let str2 = str1.repeat(3); //输出aaa
3、includes()、startsWith()、endsWith() //返回true/false
4、数组的扩展
//转换成数组:Array.from()、Array.of()、find()、findIndex()【函数】、fill()Array.from(); //转换成数组Array.of(1); //输出[1]Let res = arr.find(function(){})
5、对象的扩展
(1)对象的简洁表示法: (2)Object.is(+0,-0); //返回false (3)Object.assign():用于对象的合并,将源对象的所有可枚举属性,复制到目标对象,例:Object.assign(目标对象,源对象,源对象);十、函数的扩展
1、为函数参数指定默认值
function fn(a=10,b=20){};Fn(0,10);
2、函数的rest参数
Rest 参数形式为(“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了,rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。Function sum(a,...arr){ //其中,...arr为rest参数}
3、箭头函数:使用“箭头”(=>)定义函数
Const fn = a => a; //调用fn(1),输出1Const fn = (a,b) => a+b; //调用fn(1,2),输出3(3)Const fn = (a,b) => { a = a *2; b = b *2; return a+b; } //调用fn(1,2),输出6(4)const fn = (a,b) => ({a,b}); //调用fn(1,2),输出一个对象{a:1,b:2}
注意:
(1)箭头函数体内没有自己的this对象,所以在使用的时候,其内部的this就是定义时所在环境的对象,而不是使用时所在环境的对象;不能给箭头函数使用call、apply、bind去改变其内部的this指向; (2)箭头函数体内没有arguments对象,如果要用,可以用rest参数代替; 例:const fn = (...arr) => arr; //调用fn(1,2,3,4),输出1,2,3,4
(3)不可以当做构造函数,不可以使用new命令,否则会抛出一个错误; (4)箭头函数不能当做Generator函数。 十一、异步操作之Promise
1、基本概念
Promise: 是ES6中新增的异步编程解决方案,体现在代码中它是一个对象,可以通过Promise构造函数来实例化。new Promise(cb) //===>实例的基本使用,//三种状态:Pending(进行中) Resolved (已完成)Rejected(已失败),状态一旦改变就不会更改。
两个原型方法:
//----Promise.prototype.then()//----Promise.prototype.catch()
两个常用的静态方法:
//----Promise.all()//----Promise.resolve()//例:const p = new Promise(function(resolve,reject){ Const img = new Image(); Img.src = imgs[0]; Img.onload = function(){ resolve(this); }; Img.onerror = function(){ reject(new Error(‘图片加载失败’)); };});p.then(function(img){ //处理成功时执行的回调函数 $(“body”).append(img);}).catch(function(err){ //捕获失败时的异常 console.log(err);})
//封装函数:Function loadImg(url){ const p = new Promise(function(resolve,reject){ Const img = new Image(); Img.src = url; Img.onload = function(){ resolve(this); }; Img.onerror = function(){ reject(new Error(‘图片加载失败’)); }; }); return p;}
2、Promise.all()可以将多个Promise实例包装成一个新的Promise实例
(1)当所有Promise实例的状态都变成resolved,Promise.all的状态才会变成resolved,此时返回值组成一个数组,传递给then中的resolve函数; (2)只要其中一个被rejected,Promise.all的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。//例:const allDone = Promise.all([loadImg(imgs[0]),loadImg(imgs[1]),loadImg(imgs[2])]);allDone.then(function(datas){ //执行成功时的回调函数}).catch(function(err){ Console.log(err); //捕获失败时的异常})
3、Promise.resolve()
(1)参数是Promise实例,将不作任何修改,原封不动地返回这个实例。//例:Promise.resolve(lloadImg(imgs[0])).then(function(img){ $(“body”).append(img);})
(2)将对象转为Promise对象,然后就立即执行thenable对象的then方法
//例:Promise.resolve({ then(resolve,reject){ const img = new Image(); Img.src = imgs[1]; Img.onload = function(){ resolve(this); } }}).then(function(img){ $(“body”).append(img);})
(3)参数是一个基本数据类型或者不传参数,那么返回一个状态为resolved的Promise对象。
//例:Promise.resolve(‘miaov’).then(function(str){ Console.log(str);})//或者const p = Promise.resolve(); //console.log(p),输出一个状态为resolved的 Promise对象。
十二、ES6是如何实现模块化的?
ES6原生支持模块化了,通过自带的export(导出)和import(导入)来实现。 1、传统的模块模式基于闭包,返回“公有API”; 2、export的使用方法 方式一:export function fn() { // 导出函数}export var num = 42; // 导出变量var arr = [1,2,3];export { arr };
方式二:
function fn() {}var num = 42;var arr = [1,2,3];export {fn,num,arr}; //统一导出
3、import的使用方法
如果想导入一个模块的API中的特定命名成员到顶层作用域,使用以下语法:import { foo, bar, baz } from "foo";
ps: 这里的{ .. }语法可能看起来像一个对象字面量,甚至是像一个对象解构语法。但是,它的形式仅对模块而言是特殊的,所以不要将它与其他地方的{ .. }模式搞混了。
被罗列的标识符foo,bar和baz必须匹配在模块的API上的命名导出(这里将会发生静态分析和错误断言)。它们在你当前的作用域中被绑定为顶层标识符。
import { foo } from "foo";foo();
可以重命名被导入的绑定标识符,就像:
import { foo as theFooFunc } from "foo";theFooFunc();