ES6笔记-------2019

let const

let

TDS 暂时性死区间 :简说:在let声明一个变量前 该变量是不可用的 也就是TDS
ES6明确规定,如果作用域中存在let和const 命令,则在这个区块对这些命令声明的变量从一开始就形成封闭作用域,只要在声明该变量前去使用就会出错。
let 不允许在相同作用域内重复声明同一个变量
ES6允许块级作用域的任意嵌套
ES6的块级作用域允许声明函数的规则只在使用大括号的情况下成立 没有大括号会报错

if(true){
	function f(){}
}  //正确

if(true)
	function f(){}
//出错

const

1、const 声明一个只读的常量,一旦声明常量的值,就必须初始化,不能留到以后赋值
2、const 没有变量的体会是哪个,同样存在暂时性死区间
3、使用const 和 let 一样 不可重复声明 、、

对象的冻结 Object.freeze

总结 ES6 声明变量的六种方法

var命令 、function命令、let、const、import、class

var 有变量、函数的提升问题

解构赋值 ---- 等号两边的模式匹配

数组、对象的解构赋值
	const {a:meng,b,c}=[12,32,11];  //取别名
	const {a,b,c=9}=[12,32]; 默认值
	let json = {
    name: 'yym',
    age: 89,
    gender: '男', 
    say() {
        console.log(" i love mrn");
    }
}
let { name, age, gender, say } = json;
console.log(name, age, gender, say);
let {a,b} = {a:"yym",b:"mrn"}
console.log(a, b);
let {a:m,b} = {a:"yym",b:"mrn"}
console.log(m, b);

解构赋值可以用来接收函数的返回值(当返回的是一个对象的时候)

字符串

字符串模板:``

优点:可以随意换行  ` ${变量名称}`
eg: let name ="wang";
	let age = 18;
	let str = `这个人的名字是 ${name} ,年龄是${age}岁.`

字符串查找的一些方法

str.indexOf(要查找的内容) 返索引 没找到返回-1
str.includes(要查找的内容) 返回true/false

字符串是否以谁开头:
str.startsWith(检测内容)
字符串是否以谁结尾
str.endsWith(检测内容)
重复字符串:
str.repeat(次数)

填充字符串:
str.padStart(整个字符串的长度,填充的内容) 在该字符串的前面填充
str.padEnd(整个字符串的长度,填充的内容) 在该字符串的后面填充

函数的变化

1、函数参数的默认值

function show({x=0,y=0}={}){
			console.log(x,y)
			 }
	  show(); 
2、函数参数默认已经定义了,不能再使用let,const 声明
	 function show(a=18){  
	 let a=101;// 错误
	   console.log(a)
	  }
	  show();
	  
3.箭头函数中没有arguments
let arr = (...arg) => {
    console.log(arg)
 };
arr(1, 2, 43, 5);

// 函数的参数可以有默认值
 function meng(a = 10, b = 90) {
   console.log(a + b)
 }

…扩展运算符

...扩展运算符  Rest运算符

展开数组 
	...: [1,2,3,4]-> ...[1,2,3,4] ->1,2,3,4
	 1,2,3,4 -> ... 1,2,3,4 -> [1,2,3,4]
	 剩余参数:必须放到最后

	()=>{
			语句
			return;
		}
注意: 1、this问题。定义函数所在的对象,不再是运行时所在的对象
			2、箭头函数里面没有arguments,用‘...’
			3、箭头函数不能当构造函数

一定要注意箭头函数中this的指向

数组

循环:
1、for
for(let i=0;i 2 、while

	arr.forEach() // 代替普通for
	arr.forEach(function(val,index,arr){
	console.log(val,index,arr);
	})
	arr.map()  arr.filter()  arr.some()   arr.every()
	其实他们可以接受两个参数:
	arr.forEach/map...(循环回调函数,this要指向的对象)

	arr.map() // 非常实用 做数据交互'映射'
	正常情况,需要配合return实用 返回的是一个新的数组
	如果没有return 相当于forEach
	注意:实用map 一定要有return  
	重新整理数据结构:
		[{title:'aaa'}]  -> [{t:'aaaa'}]

	arr.filter(); 过滤 过滤一些不合格元素,如果回调函数返回true 就留下来
	返回值是一个满足条件的新数组

	arr.some();类似查找 ,数组里面某一个元素符合条件 返回true
	返回值是true /false  有满足条件的数据就会返回true 
	
	arr.every();数组里面所有的元素都符合条件 才返回true
	返回值是true /false  每一条数据都要满足条件才会返回true  
	
	arr.reduce()  // 从左往右  可用来求数组的和,阶乘
	eg: let arr = [2,2,3];
	let res = arr.reduce((prev,cur,index,arr)=>{
		return Math.pow(prev,cue)
	}) 
	console.log(res);
	
	arr.reduceRight()  //从右往左 
	
	ES6 新增一个运算符  幂 Math.pow(2,3)  或者 2**3  都可以  

for of 循环

	let arr = ['apple','banana','orange','tomato'];
	for (let val of arr){
	console.log(val); //数组的每一项
	}
	for (let index of arr.keys()){
	console.log(index); //每一项的索引
	}
	for (let item of arr.entries()){
	console.log(item); //获取数组的每一项
	}
		for (let [key,val] of arr.entries()){
		console.log(key,val); //获取数组的每一项及数组
	}

for...of...:
	arr.keys() 数组下边
	arr.entries() 数组的某一项
	for (let val of arr){
	console.log(val); //数组的每一项
	}

Array.from:
	作用:把类数组(获取一组元素,arguments...) 对象转成数组
	Array.of():把一组数值,转成数组
	let arr = Array.from('apple','banana','orange');
	console.log(arr) // arr['apple','banana','orange'];

arr.find():查找,找出第一个符合条件的数组成员,如果没有找到返回undefined

arr.findIndex() :找到的是位置 没找到返回-1;

arr.fill() 填充  // 必须要是一个有长度的数组
	arr.fill(填充的内容,开始的位置,结束位置);
	eg:  let arr = new Array(10);
	let arr1 = arr.fill('m',2,5);
	console.log(arr1);


es6新增:
	arr.indexOf()	
	arr.includes()
			str.includes() 字符串

对象的简洁语法

 1、Object.is() : 用来比较两个值是否相等
	   Object.is('a','a');
	   比较两个东西相等 ==        ===
	Object.is(NaN,NaN) ;   Object.is(+0,-0);

 2、Object.assign():用来复制对象 何必参数
 	let 新的对象 = Object.assign(目标对象,source1,source2);
 	function ajax(options){
		let defaults={
			type:'get',
			header:,
			data:{
			}
			...
		};
		let json = Object.assign({},defaults,options);
		...
	}
 	
 	ES6 引入:
 	Object.keys();
 	Object.entries();
 	Object.values();
	let {keys,values,entries} = Object;

promise 讲解

const promise = new Promise((resolve,reject)=>{
if(success){
		resolve();
	} else {
		reject();
		}
	})
	then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
	promise.then((value)=>{
		
	},(error)=>{

	})

Promise.resolve(‘aa’): 将现有的东西转成一个promise对象,resolve状态 ,成功状态等价于:

new promise(resolve=>{
 resolve('aaa');
})

Promise.reject(‘aaa’):将现有的东西转成一个promise对象,reject状态,失败状态等价于:

new Promise((resolve,reject)=>{
	reject('aaa');
})

Promise.all();
Promise.race();
Promise.try();

Promise.prototype.finally(): finally方法用于指定不管promise对象最后的状态如何, 都会执行的操作

promise
.then(result=>{...})
.catch(erroe=>{...})
.finally(()=>{...}); //无论成功或者失败 都会执行的操作

promise
.finally(() => {
// 语句
});

// 等同于
promise
.then(
 	result => {
			// 语句
		return result;
	},
	error => {
			// 语句
		throw error;
	}

Promise.all() 用于将多个Promise实例包装成一个新的Promise实例

const p = Promise.all([p1,p2,p3]);
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1,p2,p3]); 
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

模块化

a.导出内容
export 内容 
eg: export const a = 12;
export{
	a as meng,//取别名
	b as yuan
}
b.如何使用
import '路径'
import {a as aa,banana,c} from './url'

使用模块:
		

import 特点:
	a.import 'url'   url可以是相对路径,也可以是绝对路径
	b.import 模块只会导入一次,无论导入多少次
	c.import './1.js' 如果这么用,相当于引入文件
	d.有提升效果,import会自动提升到顶部,首先执行
	e.导出去模块内容,如果js文件中有定时器中=对内容进行更改,外部也会改动,不像CommonJS 会有缓存。	
	import() 类似node中的require,可以动态引入,默认import语法不能写到if之类的语法里面,返回值 ,是一个promise对象
	import('./url').then(res=>{
		console.log(res.a+res.b)
	});
优点: 1.按需加载
			2.可以写在if中
			3.路径也可以动态

类 (class)和 继承

function Person(name,age) {
this.name = name;
this.age = age;
}

Object.assign(Person.prototype, {
	getName() {
    return this.name;
 },
showAge(){
    return this.age
 }
})

let p1 = new Person();
p1.name = 'zhangdsan';
console.log(p1.getName());

es6新方法

class Person {
		//使用的时候 该方法会自动执行
	 constructor(name, age) {
   		 this.name = name,
   		 this.age = age
	}   //注意末尾没有逗号
showName() {
    return this.name
	}
}
let p1 = new Person('hua', 11);
console.log(p1.showName());

1、属性名字使用表达式的形式
let  abc = ''showAge';
		class Person {
		//使用的时候 该方法会自动执行
	 constructor(name, age) {
   		 this.name = name,
   		 this.age = age
	}   //注意末尾没有逗号
showName() {
    return this.name;
	}
	[abc](){
	return this.age;
	}
}
let p1 = new Person('hua', 11);
console.log(p1.showName());

使用的时候
console.log(p1.showAge());
或者 console.log(p1[abc]());

2、表达式的形式
const Person  = class {
		//使用的时候 该方法会自动执行
	 constructor(name, age) {
   		 this.name = name,
   		 this.age = age
	}   //注意末尾没有逗号
showName() {
    return this.name
	}
	
}
let p1 = new Person('hua', 11);
console.log(p1.showName());

注意: 1、class没有变量提升的功能,必须先声明再使用

2、this的指向问题

注:如果在使用类的时候,使用了解构赋值 要注意改变里面的this的指向问题

	this指向问题改变的几种方法  注意总结三种方法的区别
	1、fn.call(this要指向的内容,argu1,argu2); 
	2、fn.apply("this要指向的内容",[argu1,argu2]);
	3、fn.bind()

class里面的取值(getter) 和存值(setter)

	const Person  = class {
		//使用的时候 该方法会自动执行
	 constructor(name, age) {
   		
	} 
	get aaa(){
		console.log('我执行了')
	}
	set aaa(){
		console.log(‘可以通过我直接设置值’);
		}
	
}
let p1 = new Person();
p1.aaa = 'haha';
console.log(p1.aaa);

class 的静态方法:就是class自身的方法
	static aaa(){
	}
	父类.aaa();

继承:

原来的版本:
	父类:
	function Person(name,age){
			this.name =name;
			this.age = age
		}
		Person.prototype.showName = function(){
			return `名字是:${this,name}`;	
		}
		子类:
		function Student(name,age,shill){
			Person.call(this.name); // 继承属性
			this.skill = skill;
		}
		Student.prototype = new Person(); // 继承方法
		let stu1 = new Student("steven",18,''逃跑");
		console.log(stu1.showName());

	
	ES6新语法:
	父类:
	function Person(name,age){
			this.name =name;
			this.age = age
		}
		Person.prototype.showName = function(){
			return `名字是:${this,name}`;	
		}
		子类: 重点 extends
		function Student extends Person{
			// 
				constructor(name,skill){
				//调用这个方法避免覆父类的属性
					super(name);
					this.skill = skill;
				}
				showName(){
					super.showName(); //父级的方法执行
					//TODO 做子类要做的事情
					console.log(‘123’);
				}
				showSkill(){
					return  ${this.skill};
				}
		
		}
	
		let stu1 = new Student("steven",18,''逃跑");
		console.log(stu1.showName());

symbol

定义:
	let syml = Symbol('aaa');
注意:
	1、Symbol不能new 
	2、Symbol返回是一个唯一的值
	3、Symbol 使用typeof检测出来的数据类型是symbol类型的
	4、如果symbol作为json数据中的key,使用for...in 循环 不出来

generator函数或者生成器

解决异步,深度全套的问题 新增async

语法:
	定义:
	function * gen(){
			yield '';
			return '返回的结果'	
	}
	使用:
	let g1 = gen()  //结果是一个generator对象
	g1.next() // {value:'',done:true/false} done为true 表示后面没有 但是依然可以调用next() 

	eg: 	function * gen(){
			yield 'hello';
			yield 'world',
			return '返回的结果'	
	}

	let g1 = gen()  //结果是一个generator对象
	g1.next() // {value:'hello',done:false}
	g1.next() // {value:'world',done:false}
	g1.next() // {value:'返回的结果',done:true}

1、可以使用for...of 去遍历generator对象 但是return的东西不会遍历出来
2、解构赋值 
		let [a,...b] = gen(); 
3、扩展运算符
		console.log(...gen()); //return 里面的东西不会出来
4、Array.from

https://api.github.com

async 和 await

	异步实现读取文件的三种方式:
	1.promise
	let fs = require("fs");
let readFile = function (fileName) {
return new Promise((resolve, reject) => {
    fs.readFile(fileName, (err, data) => {
        if (err) reject(err);
        resolve(data);
    })
  })
}
readFile('./data/1.txt').then(res => {
	console.log(res.toString());
	return readFile('./data/2.txt');
}).then(res=>{
   	console.log(res.toString());
	})


	2.generator
	let fs = require("fs");
let readFile = function (fileName) {
 return new Promise((resolve, reject) => {
    fs.readFile(fileName, (err, data) => {
        if (err) reject(err);
        resolve(data);
    })
 })
}
function* gen() {
 	yield readFile('./data/1.txt');
	yield readFile('./data/2.txt');
 return;
}

var g1 = gen();
g1.next().value.then(res => {
 console.log(res.toString());
	return g1.next().value;
}).then(res=>{
	console.log(res.toString());
	return g1.next().value;
})

3.async
	let fs = require("fs");
	let readFile = function (fileName) {
	return new Promise((resolve, reject) => {
   	 fs.readFile(fileName, (err, data) => {
       	 if (err) reject(err);
       	 resolve(data);
   	 })
 })
}
async function fn(){
	let f1 = await readFile('./data/1.txt');
	console.log(f1);
 let f2 = await readFile('./data/2.txt');
	console.log(f2);
}
fn();

async

语法:
async function fn(){ //表示异步 这个函数里面有异步操作
	letresult = await xxx   //表示后面结果需要等待
}

async的特点

1、await 只能放到函数async里面
2、相比generator语义化更强
3、await后面可以是promise对象,也可以是数字,字符串,布尔
4、async函数返回是一个promise 对象
5、只要await语句后面promise状态变成reject,那么整个async函数会中断执行

async function fn(){
	try{
		await Promise.reject('出现问题了);
	}catch(e){}
	let a = await Promise.resolve('success');
	console.log(a);
	}
	fn().then(res=>{
		console.log(res);
	}).catch(err => {  //捕获错误
	console.log(err)
})

如何解决async函数中抛出错误,影响后续代码

a. try(){
}catch(){
}
b.promise本身catch()
建议在await的外部加上try(){}catch(e){} 
内容没有关联关系的时候也可以使用Promise.all([]);
eg:
	async function fn(){
		let [a,b,c] = await Promise.all([
			readFile('./data/a.txt'),
			readFile('./data/b.txt'),
			readFile('./data/b.txt')
		]);
		console.log(a.toString());
		console.log(b.toString());
		console.log(c.toString());
	}
fn();

Set和weakSet 数据结构

Set 类似数组,但是里面不能有重复的值

set用法:
new Set([‘a’,‘b’]); 参数是一个数组 得到的结果是一个对象

eg:
	let set = new Set(['q','w']);
	console.log(set);//Set { 'q', 'w' }
	console.log(typeof set);  //object
	
	set.add('vvv'); // 往set里面添加一项
	set.delete('a'); //  删除一项
	set.has('a');   // 判断set里面有没有后面传过来的值
	set.clear();  //  清空
	set.size //通过size属性获取长度
	
	可以使用for ... of  来遍历set   forEach()

	数组去重:
		let arr= [1,2,3,2,3,6,5,8,0,6,54,4,4,3];
		let newArr = [...new Set(arr)];
	set数据结构变成数组: [...set];

http://www.potree.org/  3D

Set([]) 里面传入的是数组

WeakSet({}) 里面传入的是json 不可以直接在定义的时候传值会报错

		 没有size属性 没有clear()方法

Map 和 WeakMap 类似于json

注意:json的key只能是字符串 map的key 可以是任意数据类型

用法:
	let map = new Map();
	map.set(key,value);  // 设置值
	map.get(key); //获取值
	map/delete(key); // 删除一项
	map.has(key) 判断有没有某一项
	map.clear() 清空	
	可以是用for..of  进行循环遍历
	
	WeakMap()的key只能是对象

数字(数值)变化

Number.isNaN(NaN) -->true
Number.isFinite(a)          // 判断是不是数字
Number.isInteger(a)         // 判断数字是不是整数
Number.parseInt()           // 判断是不是整数
Number.parseFloat();		//判断是不是浮点数

安全整数: -(2^53-1) 到 (2^53-1)

 Number.isSafeInteger(a); //判断是不是最大整数 
 Number.MAX_SAFE_INTEGER  最大安全整数
 Number.MIN_SAFE_INTEGER  最小安全整数
Math:
		Math.abs(); Math.sqrt();
		Matn.sin(); Math.cos(); 
		新增:
		Math.trunc() 截取,只保留整数部分
				Math.trunc(4.99) --> 4
				Math.trunc(4.09) --> 4
		Math.sign()  判断一个数到底是正数,负数  0  -0
			Math.sign(-5)  ---> -1
			Math.sign(5)  ---> 1
			Math.sign(0)  --->0
			Math.sign(-0)  ---> -0
		Math.cbrt() 计算一个数的立方根

新增的一些东西

1.命名捕获:  用在正则表达式
			语法:(?<名字>)
			eg: 
				let str = "2019-08-21";
				let reg = /(?\d{4})-(?\d{2})-(?\d{2})/;
				let { year, month, day } = str.match(reg).groups; //使用命名捕获之后会添加一个groups属性(是一个对象) 里面存储相关信息 
				console.log(year, month, day);  // 2019 08 21 
	反向引用:  \1     \2     $1   $2
	反向引用命名捕获:
			语法:\k<名字>
			eg: let reg=/^ (?welcome)-\k$/;
					//  匹配: aaa-aaa
					let reg=/^ (?welcome)-\k-\1$/;
					//  匹配: aaa-aaa-aaa

	替换:
		
		let str = '2019-08-21'; //转化成 08/21/2019
		let reg = /(?\d{4})-(?\d{2}-(?\d{2})/;
		str = str.replace(reg, '$/$/$');
		console.log(str);
	
	2.dotAll模式   s
		之前'.'在正则表达式里面表示匹配任意东西,但是不包括\n 
		let reg = /\w+/gims;
	3.标签函数
		 语法: 
		 声明  function fn(arg){
		 }
		 使用: fn`要传入的参数`

正则表达式:
以^开头 以$结尾  /^$/

ES6笔记-------2019_第1张图片

proxy 代理

扩展或者增强对象的一些功能
Proxy的作用:比如Vue中的拦截
预警、上报、扩展功能、统计、增强对象等等
proxy 是一种设计模式,代理模式

语法: new Proxy(traget,handler(是json));
let obj = new Proxy(被代理的对象,对代理对象要进行的操作)
handler{
		set(){}.//设置的时候做的事情
		get(),//获取的时候做的事情
		deleteProperty(){},// 删除 拦截
		has(){},//是否包含某个东西
		apply() //调用函数处理  拦截方法
	}

Reflect.apply(调用的函数,this指向,参数数组);

Reflect:反射
Object.assign() 语言内部的方法
Object.defineProperty放到Reflect对象身上,通过Reflect对象身上直接拿到语言内部的东西。
‘assign in Object’ -> Reflect.has(Object,‘assign’);
delete json.a -> Reflect.deleteProperty(json,‘a’);

ES6笔记-------2019_第2张图片

你可能感兴趣的:(es6语法)