通俗易懂之ES6

ES6

es6是js的最新标准,新增了很多概念,目前大部分浏览器都支持ES6,ie7~11除外。

let

	let和const也是声明变量的关键字,和之前的var一样,不过有一些特殊。
  1. let 声明的变量只在let命令所在的代码块有效。

     	例:
     		if(true){
     			let a=0;
     			console.log(a)//  0
     		}
     		console.log(a) //报错 a is not defined  找不到a这个变量  a变量只在{}内才有效,{}外无法找到。
    
  2. let同一个变量只能声明一次,多次声明会报错。

     	例:
     		let a=0;	
     		let a=1; //报错 'a' has already been delared
    
  3. let不存在变量提升,在声明语句前调用变量会报错

     console.log(a) //undefined
     var a=10; 
     console.log(a)//10
    
     console.log(b) // 报错b is not defined
     let b=10; 
    

const

const声明一个只读变量,声明后不允许在改变,否则会报错。

注意:

const保证的是内存地址保存的数据不能改动,但是如果是声明对象、数组、函数时,变量指向的内存地址只是一个指向数据的指针,const只能保证这个指针固定,但是指针指向的数据就不能控制了。

解构赋值

数组解构
let [a,b,c]=[121,222,321]
//打印  a =121  b=222  c=321  可以理解为  let a=121,b=222,c=321
数组也可以进行嵌套
let [a,[[b],c]]=[1,[[2],3]]
//打印 a=1 b=2 c=3   只要位置对应上就可以把右边的值付给左边
let [a,b,c]=[1,,3]
// 打印 a=1 b=undefined c=3  中间有空值不会影响其他的赋值
let [a,...b]=[1,2,3]
//打印 a=1 b=[2,3]     ...  是剩余运算符 表示剩下的值都付给该变量
字符串解构
let [a, b, c, d, e] = 'hello';
//打印 a='h' b='e' c='l' d='l' e='o'   当字符串可以遍历时,就可以进行解构赋值
解构默认值
let [a = 2,b=a] = [1];
//打印 a=1 b=1
//解构赋值的规则:先按位置在右边寻找左边变量对应的值,因为a在右侧有对应的值, 那么a变成右边的1,忽略a=2这个默认值,b在右边没有对应的值,那他的默认值就是b=a,所以b=a=1
let [a = 3, b = a] = [];     // a = 3, b = 3
let [a = 3, b = a] = [1];    // a = 1, b = 1
let [a = 3, b = a] = [1, 2]; // a = 1, b = 2
对象结构
//基本解构赋值
	let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
	// foo = 'aaa'
	// bar = 'bbb'
 
	let { baz : foo } = { baz : 'ddd' };
	// foo = 'ddd'
//嵌套解构赋值
 	let obj = {p: ['hello', {y: 'world'}] };  对象通过 {属性:值}来进行赋值,数组只要位置对应即可
	let {p: [x, { y }] } = obj;
	// x = 'hello'
	// y = 'world'
//可忽略解构赋值
	let obj = {p: ['hello', {y: 'world'}] };
	let {p: [x, {  }] } = obj;
	// x = 'hello'   即使右边的有多余的值,只要其他位置对应 即可解构赋值,不会受到影响
//不完全解构
	let obj = {p: [{y: 'world'}] };
	let {p: [{ y }, x ] } = obj;
	// x = undefined      左侧有多余的变量,右边没有对应的值时 默认undefined
	// y = 'world'			可以理解成 只要 右边有值的对象或数组 在左侧都能找到对应位置 即可解构赋值,有点类似数学中的  子集  即{a,b,[c]}={1,2} 
//剩余运算符
	let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
	// a = 10
	// b = 20
	// rest = {c: 30, d: 40}   剩余的值以新对象的方式付给rest
//解构默认值
	let {a=10,b=2} ={a:3};
	//a=3 b=2
	let {a:aa=10,b:bb=5}={a:3};  这里的a  可以看做是两边联系的变量
	//aa=3 bb=5    
	//如果是let {a:aa=10,b:bb=5}={b:3}
	//那么打印出来就是 aa=10 bb=3

symbol

symbol是新的原始数据类型,通常用来表示独一无二的值,我个人理解相当于是一个不能改变的常量,就像html的id一样 是唯一的,最大的用法,是用来给对象定义属性名。

基本用法

let sy=symbol("kk")   /"kk”不是这个sy的值,他只是sy的描述
console.log(sy)   //symbol("kk")
console.log(typeof sy)   //"symbol"

let sy1=symbol("kk")
console.log(sy === sy1)  //false    尽管相同参数,但是sy和sy1是不同的两个变量,可以把symbol()想象成一个生成随机数的方法,每次调用它都会产生一个随机数来表示这个变量,每次的结果都是独一无二的。

使用场景

当一个对象属性过多时,可以用symbol来给对象定义属性
let sy=symbol("key");
let obj={};
obj[sy]="kk"
console.log(obj) //{symbol("key1"):"kk"}

let sy=symbol("key");
let obj={ 
	[sy]:"kk"
};
console.log(obj) //{symbol("key1"):"kk"}

let obj= {};
Object.defineProperty(obj, sy, {value: "kk"});
console.log(syObject);   // {Symbol(key1): "kk"}

symbol.for()和symbol.keyFor()

symbol.for("Yellow")是现在全局搜索,如果没有以"Yellow"作为参数登记的symbol,那么新建一个symbol("Yellow"),并登记在全局以供搜索,如果下次搜索搜索到已经有这个symbol,那么就会直接返回。所以用symbol.for()创建的参数一样的symbol,其实是同一个,是相等的
let yellow1 = Symbol.for("Yellow");
let yellow2 = Symbol.for("Yellow");
yellow1 === yellow2;     // true

symbol.keyFor()返回一个已登记symbol的key
symbol.keyFor(yellow1)   //"Yellow"

注意事项

  1. symbol作为对象属性使用时不能通过.调用,只能使用[ ]
  2. symbol不能进行任何运算(+ - * /)
  3. symbol不会出现在for…in for…of的循环中,要读取对象的symbol属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
  4. ES5声明常量通常用const,但是const声明的常量值是有可能相等的,比如声明两个值都为"red"的常量,在判断这两个常量时就会出现问题,所以symbol是用来声明独一无二的常量的。

MAP对象与SET

map对象

map对象和object类似,不同的是:

  1. obj对象键只能是字符串或symbol,map对象的键可以是任意值。

     var myMap = new Map();
     var keyString = "a string";   //当key是字符串
    
     myMap.set(keyString, "2333");
      
     myMap.get(keyString);    // "2333"
     myMap.get("a string");   // "2333"
                              // 因为 keyString === 'a string'
    
     var keyObj = {},   //当key是对象
     myMap.set(keyObj, "和键 keyObj 关联的值");
     myMap.get(keyObj); // "和键 keyObj 关联的值"
     myMap.get({}); // undefined, 因为 keyObj !== {}
    
     var keyFunc = function () {}, // 函数
     myMap.set(keyFunc, "和键 keyFunc 关联的值");
     myMap.get(keyFunc); // "和键 keyFunc 关联的值"
     myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
    
     
     myMap.set(NaN, "not a number"); //key是NAN
     myMap.get(NaN); // "not a number"
     var otherNaN = Number("foo");
     myMap.get(otherNaN); // "not a number"
    
  2. map对象键值数量可以通过sizi属性获取,obj对象需要手动计算。

  3. object都有原型,原型中的键名可能和自身的键名产生冲突。

set对象

set对象允许存储任何类型的唯一值,因为里边的值都是唯一的,所以存的时候会判断是不是恒等,比如我存了1 后边再存1的时候就会判断 已经有1了 就不会重复存储了。

	let mySet = new Set();

	mySet.add(1); // Set(1) {1}
	mySet.add(5); // Set(2) {1, 5}
	mySet.add(5); // Set(2) {1, 5} 这里体现了值的唯一性
	var o = {a: 1, b: 2}; 
	mySet.add(o);
	mySet.add({a: 1, b: 2}); 
	// Set(5) {1, 5, "some text", {…}, {…}} 
	// 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储

特殊情况

因为要判断恒等,有几种特殊情况需要记住:
1.+0和-0在判断唯一性的时候是恒等的,所以不重复。
2.undefined和undefined是恒等的,所以不重复。
3.NaN和NaN是不恒等的,但是在set只能存一个,所以不重复

class

相当于构造函数的另一种写法

class Person{ //定义了一个叫Person的类
	constructor(name,age){ //constructor是一个构造方法,用来接收参数
		this.name=name;
		this.age=age;

	}
	say(){	//这是一个类的方法,注意千万不要加上function
		return "我的名字叫"+this.name+"今年"+this.age+"岁了"
	}
}

	var obj=new Person("laotie",88)
	console.log(obj.say()) //我的名字叫laotie,今年88岁了

注意
在类中声明方法的时候,千万不要给class加function关键字
方法之间不要用逗号分隔,否则会报错
class不存在变量提升,所以需要先定义再使用

promise对象

promise是异步编程的解决方案,有时我们需要在异步运算结束后进行操作,使用promise就可以直到异步什么时候结束,并在结束时执行要执行的操作。

特点

promise有三种状态 pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,其他操作都无法改变这个状态。
Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(要么成功,要么失败,已经定型)。

基本用法
const p1 = new Promise(function(resolve,reject){ //resolve是成功执行的函数,reject是失败执行的函数。
	resolve('success1');  //成功执行时会把参数传进去
	resolve('success2');//失败执行时会把参数传进去,这两个只会执行其中一个,不是失败就是成功。
}); 

p1.then(function(value){     //then()方法可以有两个参数,就是对应p1对象里fuction的resolve成功回调和reject失败回调。
    console.log(value); // success1
});
//上边可以理解成
const p1 = new Promise(function(resolve,reject){ 
resolve('success1');  //成功执行时会把参数传进去
//resolve=function(value){     //value就是传进来的"success1"
    console.log(value);
}

resolve('success2');//失败执行时会把参数传进去,这两个只会执行其中一个,不是失败就是成功。
}); 

缺点

1.无法中途取消promise,一旦新建成功那么就会立即执行,无法取消。
2.如果不设置回调函数,那么promise抛出的错误不会返回到外部。
3.当处于pending时,无法直到代码执行到具体哪一步(刚刚开始执行还是快要结束了)。

Then()

then方法可以接受两个参数,一个是对应resolve的回调,一个是对应reject的回调,所以我们能够分别拿到他们传过来的数据。同时,then()方法可以多次调用,每次调用return会返回一个resolve或reject的promise对象用于接下来的链式调用。

const p = new Promise(function(resolve,reject){
  resolve(1);
}).then(function(value){ // 第一个then // 1
  console.log(value);
  return value * 2;
}).then(function(value){ // 第二个then // 2
  console.log(value);
}).then(function(value){ // 第三个then // undefined
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){ // 第四个then // resolve
  console.log(value);
  return Promise.reject('reject'); 
}).then(function(value){ // 第五个then //reject:reject
  console.log('resolve:' + value);
}, function(err) {
  console.log('reject:' + err);
});

catch()

catch方法和then的第二个参数一样,用来指定reject的回调,而且在执行resolve的回调时,如果代码出错了,那么不会卡死报错,而是进到这个catch方法中,相当于try/catch

all()

并行异步操作,在所有异步操作执行完后才执行回调(谁跑得慢以谁为准)
race()的用法
相当于谁跑得块以谁为准,当异步加载资源时,可以再写个延时函数,如果延时函数先执行,那么就提示加载超时

箭头函数

就是将之前的函数写法简单化
左边是函数名和参数 =>  右边是函数体
var f=v=>v  
	//上面相当于var f=function(v){return v}


var f=(a,b)=>a+b //当有多个参数,用()括起来
	var f=function(a,b){return a+b}

var f=(a,b)=>{
	当函数体有多行代码时,用{}包裹起来
}

当返回对象时,要区分代码块,用({})包裹代码块
	报错
var f=(id,name)=>{id:id,name:name}

	不报错
var f=(id,name)=>({id:id,name:name})

注意:
箭头函数里没有this(构造函数里的this指的是写函数时那个外部的this)、super、arguments和new.target绑定
箭头函数不可作为构造函数 不能用new命令

扩展运算符

对象中的扩展运算符 … 用来取出参数对象中所有可遍历的属性,拷贝到当前对象中
let bar={a:1,b:2}
let baz={…bar} //{a:1,b:2}
如果用户自定义的属性,放在扩展运算符的后面,则扩展运算符内部的同名属性会被覆盖

扩展运算符是浅拷贝,拷贝基础数据类型没问题,但是拷贝引用数据类型时,会拷贝引用的地址,当拷贝对象变化的时候,源对象会跟着改变

数组中的扩展运算符

可以将数组转换为参数序列
	function add(x, y) {
	  return x + y;
	}

	const numbers = [4, 38];
	add(...numbers) // 42

可以复制数组
	const arr1 = [1, 2];
	const arr2 = [...arr1];//[1,2]

可以和解构赋值一块用
	const [first, ...rest] = [1, 2, 3, 4, 5];
	first // 1
	rest  // [2, 3, 4, 5]
可以把字符串转成真正的数组
	[...'hello']
	// [ "h", "e", "l", "l", "o" ]

用于数组赋值时,只能放在最后一位,否则报错
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值