各位学习es6的小可爱们,在学习ES6之前,强烈建议先学习es5,精读学习任一类的es5文档,至少1-3遍。说明:本学习之路主要是针对自己学习复习的,比较杂糅。大家可以按照自己的喜好整理。
ES6如何学
- 快速统揽,然后使用
- 边使用边加深印象
- ES6教程、MDN
新版变量声明let const作用域
// a = 1;// 含义不明-不要用
// function fn() {
// if(true) {
// console.log(a);
// } else {
// var a = 1;
// console.log(2);
// }
// }
// fn()
// {var a}
// console.log(a)
// var a = 1
// 上面两种是es3的,下面两种是es6
// let a = 1
// const a = 1
// 1.其实let的作用域很简单,就是只看花括号,花括号外面就报错
// 2.let的作用域在最近的{}之间
// 3.如果你在let之前使用a,那么报错
// 4.如果你重复let a,那么报错
// const
// 1,2,,3同上
// 4只有一次赋值机会,而且必须在声明的时候立马赋值
// {let a= 2}
// console.log(a)
{
let a = 1;
{
console.log(a);// 不定义就使用,报错;Temp Dead Zone临时性死区
let a = 2; // 所谓暂时死区,就是不能在初始化之前,使用变量。
{let a = 3;}
}
}
其实我想实现每次点击一次,打印出对应的i;但是结果差强人意,但是let完美的解决了【或者es5的立即执行函数也可以】
// var liTags = document.querySelectorAll('li');
// for(let i=0;i<liTags.length;i++) {
// liTags[i].onclick = function() {
// console.log(i);
// }
// }
// 插一嘴,es5中的立即函数的写法就是为了实现let块级作用域的概念的。
新版函数: 箭头函数
es3
// 具名函数
function xxx(p1,p2){
console.log(1)
return 2;
}
// function是匿名函数 - =是赋值 - let xxx是声明
let xxx = funtion(p1,p2){
console.log(1);
return 2;
}
es6
// 箭头函数
let xxx = (p1,p2)=>{
console.log(1);
return 2;
}
let xxx = p1 => { // 如果只有一个参数,则可以不加括号
}
let xxx = (p1,p2) => p1+p2 // 如果函数体只有一句,可省略花括号
let xxx = p1 => p1+2 // 圆括号和花括号一起简化
为什么要出现箭头函数,它主要解决了什么
它的出现是为了解决this这个关键字。【重点:this是call的第一个参数】
es3支持this,es6也支持this。但是用箭头函数弱化了this的用法
--------------------------------------------------------------------
function f(p1,p2){
// let p1 = arguments[0];
//let p2 = arguments[1];
console.log(p1);
}
f('abc')
p1的值是由f(这个玩意儿决定的)
p2的值是由f(不是这个,这个玩意儿决定的)
arguments = [不是这个,这个玩意儿决定的]
---------------------------------------------------------------------
let object = {
name: 'obj'
hi: function(/*this,*/p1,p2){
console.log(this.name)
}
}
object.hi(/*object, */1,2)
object.hi.call(object, 1,2)
p1的值是由object.hi(这个玩意儿决定的)
p2的值是由object.hi(不是这个,这个玩意儿决定的)
this的值是由 这个玩意.决定的hi()
this的值是由object.hi.call(这个, 1,2)
以前的函数有this,this是call的第一个参数;es6的箭头函数没有this[跟变量a是一样一样的,外面是啥里面就是啥],【注:函数的所有参数都应该放到函数列表里面:类比pathon】
&箭头函数的this就类同于普通变量,a咋用,this就咋用
有时间可关注coffeeScript,es6的很多语法都是跟它抄的。
: if(response & reponse.data) {balabal...} <==> reponse?data?.user
-----------------------------------------------------------------------
异类,箭头函数在vue中又做了妥协
this === window:new Vue({
data(){},
methods:{
onClick(){ //就是function,此处就是老的写法,不过做了简化
let f = ()=>{
console.log(this);
}
},
}
})
三个点运算 & 新版字符串
1.函数与对象的语法糖
1.1函数的默认参数
function sum(a,b){
b = b || 0
c = c || 0
d = d || 0
return a+b
}
sum(11)
-----------------------------------------------------------------------
function sum(a=0,b=0){
return a+b
}
sum(1)
1.2 剩余参数
es5
function sum(){
let result = 0;
for(let i=0;i<arguments.length;i++){
result += arguments[i];
}
return result
console.log(arguments)
}
sum(1,2,3,4,5,6,7,8)
---------------------------------------------------------------------
function sum(message){
let result = 0;
for(let i=0;i<arguments.length;i++){
result += arguments[i];
}
return message + result
console.log(arguments)
}
sum("结果是:",1,2,3,4,5,6,7,8)
------------------------------------------------------------------
es6
function sum(message,...numbers){ // 方法:优
let result = 0;
// for(let i=0;i<numbers.length;i++){
// result += numbers[i];
//}
// numbers是真正的数组
result = numbers.reduce((p,v) =>p+v,0)
return message + result
}
sum("结果是:",1,2,3,4,5,6,7,8)
-------------------------------------------------------------------
function sum(message) {
方式一 let args = Array.prototype.slice.call(arguments)// es5提供给伪数组变成真数组的方法
方式二 let args = Array.from(arguments)//es6提供给伪数组变成真数组的方式
方式三 let args = [...arguments]// es6提供给伪数组变成真数组的方式
...
return message + result
}
sum('结果是',1,2,3,4,5,6,7,8)
1.3 展开操作
let array1 = [1,2,3,4,5,6]
// array1是array2的后三项
let [a,b,c,...array2] = array1;
console.log(array2)
let [,,,...array3] = array1;
let [...array4] = array1
//在array1前面加上0
let array5 = [0,...array1]
//等价于es5中
let array6 = [0].concat(array).concat([7])
1.4 解构赋值
// 交换两个数的值
let a=1;
let b=2;
// temp = a
// a= b
// b = temp
1.[a,b]=[b,a];
console.log(a,b)
----------------------------------------------------------------------
2. [a,b,...rest] = [10,20,30,40,50]
----------------------------------------------------------------------
3.let {name,age} = frank
// 第一种写法是程序员写了七八年的写法
// var frank = {name:'frank',age:18,gender:'male'}
// var name = frank.name
// var age = frank.age
// var gender = frank.gender
// 第二种写法【解开这个东西的结构,然后进行赋值操作】
var {name,age,gender} = frank; // = {name:'frank',age:18,gender:'male'}
var [a=4,b=6] = [1] // 左边可设置默认值,右边如果没有值,就使用默认值
var {name:xingming} = frank
var frank = {
name:'JACK',age:18,gender:'male',child:{
name:'jerry',age:1,gender:'male'
}
}
// 取child的name,age,gender,把age作为两个变量声明,name,gender的重命名一下,如果没有取到值,就给一个默认值tom
var {child:{name:xingming='Tom',age,gender:gender}} = frank
----------------------------------------------------------------------
4 对象的拷贝
let objA = {name: {
x:'a'
}}
//let objB = Object.assign({},objA) // 浅拷贝
let objB = {...objA} // 浅拷贝
// 对象的合并
var objA = {p1:1,p2:2}
var objC = {p1:1111,p2:333}
// var objB = Object.assign({}, objA,objC)
let objB = {...objA,...objC}
//总:首先考虑三个点,其次object.assign,最后就是for循环
----------------------------------------------------------------
更多语法看mdn解构赋值
上面全部是解构的例子,那有没有合构呢?请看对象属性加强
5.对象属性加强
1.var x = 1
var y = 3
var obj = {
"x":x,
"y":y
}
// es6看见了,key和val是一样的,那可以简写成
var obj = {x, y}
var obj = {x:1,y:2}
var {x, y} = obj
var [x,y] = [1,2] // 右边是[x:1,y:2]
2. var key = 'x'
var value = 'y'
var obj = {}
obj[key] = value // 对的
// {"x":"y"}
var obj = {
[key] : value // es6自动给他加上中括号;如若不加会当成字符串处理,而不是变量key
}
3.函数属性可以省略function
var obj = {
sayHi(name='jack'){}// 推荐
sayHi:function(name){}
}
2、新版字符串
插值(字符串中插入变量)
var string = ${name}是一个${person}
迭代器与生成器
1、字面量增强
1,[1,34,45],'hhhh'这种通俗易懂的,不需要进行转化的,能看懂的,就是字面量。
2、Symbol和迭代器
2.1 Symbol定义的是独一无二的,俗称'身体的印记',独一份的
2.2 迭代器
遍历,即一个一个的访问,一般是有限的。
迭代跟遍历很相似。【迭代即升级:zhihu V1.0-> zhihu V2.0-> zhihu V3.0】,一般是无限的...
```
// function 发布器() {
// return {
// next:undefined
// }
// }
// 发布器()
function 发布器() {
var _value = 0
return {
next:function() {
_value += 1
return {
value: _value
}
}
}
}
a = 发布器()
a.next()
a.next()
a.next()
-----------------------------------------------------------------------------
function 发布器() {
var _value = 0
var max = 10
return {
next:function() {
_value += 1
if(_value === max){
return {value:_value,done:true}
} else {
return {
value: _value,
done: false
}
}
}
```
3、生成器 & for of
1、生成器是迭代器生成的语法糖[在函数前面加上一个✳号,在值的前面加上yield]
```
上面的代码用es6里面的写法是:
function *发布器() {
var version = 0
while(true) {
version += 1
yield version // 这几行代码只执行一遍 原因是yield:他会吼出来
}
}
a.next()
```
2、for of是迭代器访问的语法糖
数组可以迭代,对象不能迭代【可以自定义迭代器,引入Symbol[iterator],参考mdn】【数组和对象的原型不一样】
```
```
4、总结
学习要趁早,定一个三年前端小目标【基础学扎实】,定一个五年前端中目标【懂原理,再学一门技术】,定一个10年大目标【达到什么样的】
新版对象
1、如何创建对象
1、var a = new Object() // es5的写法
2、var b = Object.create(null) // es6真正的生成一个空对象
3、var c = Object.create(object.prototype) // 1和3是等价的,因为有原型
4、var d = {} // 跟1是一样的,都是es5的写法
2、属性修饰符
Object.defineProperty() Object.getProperties() Object.create()
ES6模块
1、模块化
一个豆腐切成两个块,类比:一个代码分成两个块
- 模块(豆腐块)
- 依赖:(用到了)简称:男生依赖于富婆,即男生用富婆的钱和地位,哈哈哈
- 导出:(给别人用)
如何导出有名字的模块{name};如何导出没有名字的模块(default);如何导出换个名字的模块(name as name1);全部导出用*详见MDN的import
2、Babel wabpack parcel
浏览器不支持import,export module,js程序员就造了babel wabpack的升级就是parcel 插播:目前不会命令行的程序员就要嗝屁儿了。
新版的类
1、原型
原型 === 共有属性
2、类
类:拥有相同属性的对象 构造函数:用来创建某个类的对象的函数 自有:对象自身的属性 共有:对象原型里面的属性
promise
1、回调与回调地狱
调函数:在一个函数名后面加上括号
function fn() {
}
fn()
function fn2(){
fn() // 调函数
} // 回调
回调:把一个函数A传给另外一个函数B调用,那么A就是回调函数
缺点:1、回调地狱
2、不知道怎么使用Node、Jquery只能强行背下来【传递参数方式不一样】
回调地狱:回调里面套回调套回调套回调套回调套回调逃回调
function 获取用户信息(fn){fn('sds')}
获取用户信息(function(用户信息){
保存用户信息(用户信息,function(){
获取另外一个用户的信息(function(另外一个用户的信息){
保存用户信息(另外一个用户的信息)
})
})
})
解决回调地狱的方式:1、给每一个回调函数起名称,也就是解开回调地狱的方式,缺点,变量可能访问不到
2、Promise
2、Promise的用法
function 获取用户信息(){
return new Promise(function(resolve, reject){
console.log('第一次获取用户信息')
resolve('姓名zz')
})
}
function 打印用户信息(用户信息){
return new Promise(function(resolve, reject){
console.log('用户信息')
resolve('')
})
}
function 获取另一个用户信息(){
return new Promise(function(resolve, reject){
console.log('第二次获取用户信息')
resolve('姓名zz')
})
}
获取用户信息()
.catch(function(){})//
.finally(function(){})//
.then(打印用户信息)
.then(获取另外一个用户信息)
.then(打印用户信息)
注:等多个promise都执行完了之后,在统一交给一个函数执行,用promise.all
promise.race跟all相反,只要任何一个成功了,我就调用
这样写,也有回调的意思在,就有了async await。注意:一般async await是跟try catch一起来用的
try {
let 用户信息 = await 获取用户信息('gg')
} catch(error/*错误理由*/){
console.log('error')
}
ES6新增的数据类型【2-8】
Symbol:基本类型,不是对象,window.symbol;返回的值是唯一的;可以作为对象的key;symbol做为对象的隐藏属性
set类型(集合)
Map类型(映射)
WeakMap类型:弱引用,弱引用不属于GC回收的范围,自动消失,是虚无的东西;key只能是对象
WeakSet类型:弱引用,弱引用不属于GC回收的范围,自动消失,是虚无的东西;没有entries方法,无法列出所有的值
TypedArray
Symbol('xxx') !== Symbol('xxx')
ES6新增的API
Object.assign:把一个对象的属性复制到另外的属性上面,是一个浅拷贝
a={
name:'frank',
age: 18
}
b= {b:1,c:2}
object.assign(a,b)
Array.from: 把伪数组变成数组 a= Array.from(a)
a = Array.prototype.slice.call(a, 0) // es5
创建一个长度为n的数组
Array.from({length:5}) //es6
Array.apply(null, {length:5}) // es5
new Array(5) // 不能实现,没有下标
find:找到满足条件的一个就停下来
finIndex: 不找哪个对象,找到对象的位置
filter: 过滤出满足条件的所有对象
includes: 判断一个字符串是否包含另外一个字符串,返回true或false。跟他相似的有indexof,search,substr...,match正则
Proxy和Reflect
1、reflect: 反射
reflect.get(target,name,receiver)
reflect.set
reflect:都有对应的方法代替
2、代理 proxy
async & await
复习:promise
a.它会通过一个隐式的promise的返回其结果,b.但是如果你的代码使用了异步函数,,它的语法和用法会更像是标准的同步函数(try catch)
Promise.all([猜大小('大'),猜大小('大')])
.then((x) => {console.log(x)},(y)=>{console.log(y)})
async function test() {
try {
let n = await Promise.all([猜大小('大'), 猜大小('大')])
} catch (error){
}
}
test()