阅读 58

事关我对于ES6常用语法

写在前面: 这里是关于ES6的常用语法一些总结和记录,以及一些比较重要的概念进行强化记忆

暂时性死区

在let命令声明该变量之前,都是不可用的。ES6规定,如果区块中存在const和let命令,这个区块对这些命令创建的变量,形成封闭作用域,凡是在声明之前使用都会报错。
let是块级作用域,是一对{}所包含的作用域
var是局部作用域,是一个函数体所包裹的作用域.

变量提升

var命令创建的变量会在一开始编译的时候被提前创建,只不过值为undefined,随后再给变量赋值。

Map类型

实质是数组,但类似于对象,数组一般是有下标和值,map的下标可以被定义名称,一般对象键值对中的键为字符串,但是Map的键可以是其他字符型,如number类型。方法有:

  1. Map.size(长度),
  2. Map.get(获取),
  3. Map.set(添加),
  4. Map.has(判断),
  5. Map.delete(删除),
  6. Map.clear(清空),
  7. Map.keys(所有键),
  8. Map.values(所有值),
  9. Map.forEach(遍历)

遍历方法

for of 循环遍历和for in 用法差不多。 for(item,index)of itemList.

Arror.from()

把类数组对象(NodeList)和可遍历对象(Set,Map)转成真正的数组,扩展运算符也能把类数组变成数组。

find和和findIndex

数组的find()和findIndex()方法用于找值和下标,还有比如indexOf();参数是一个回调函数,可以有三个参数,当前值,当前位置和当前数组。

[1, 5, 10, 15].findIndex(function(value, index, arr) { return value > 9;}) // 2

隐式类型转换

string和number相互转换: let int = "15"; int = +int; (int:15);

一元运算符 + 也可以把数字字符串转换成数值: + "42"; // 42

string和布尔转换: +true(1); +false(0);

parseint的第二个参数可以设置转换进制:

parseInt("0x10"); // 16			
parseInt("11", 2); // 3
复制代码

数值取整,可以用math方法,向上向下取整 , 也可以用 23.9 | 0 (23), -23.9 | 0 (-23)

使用位或运算符,正数向下取整,负数向上取整.

截取方法

slice(start,end):裁剪,不改变原数据

data = 123456789;slice(0,data.length - 3) // 123456 

裁剪方法: splice(start,num,new) 开始位置,删除个数,要添加的,返回被删掉的数据;

拼接方法: join(","),把数组用,拼接起来变成字符串;

平均切割:split() ,把字符串一个个分开成一个数组;
复制代码

事件循环(Evenloop)

宏任务(tasks):如定时器,循环器,I/O,以及script;

微任务(jobs):如promise,观察者(object.observe) node里面的process.nexttick;

消息队列:先进先出.

机制:主线程执行代码.
复制代码

1.同步代码优先执行,碰到异步请求加入消息队列,分为宏任务队列和微任务队列。

2.同步代码全部执行完成,开始执行消息队列的请求,优先级:微任务>宏任务.<br>
3.先执行完所有微任务,如果微任务执行过程中又有新的微任务或者宏任务,依旧分别加入消息队列<br>
4.如果第一遍微任 务执行完毕后没有新的微任务加入则开始执行宏任务,否则继续执行微任务,一直循环执行这个操作,叫做事件循环,直到消息队列中不存在微任务和宏任务。<br>
5.同步代码和微任务执行完成,开始执行宏任务,如果宏任务中包含微任务则下次循环会再优先执行微任务,然后再执行宏任务。<br>
复制代码

原型和原型链

因为每个对象都有proto属性,每个实例的proto都指向其构造函数的prototype,所以会有原型链.

Class 类

class相当于new了一个实例,里面所有方法注册在实例的原型上,constructor表示默认方法,里面return this(默认对象)

static(静态方法)

声明里面所有的方法均不注册在原型上.所以不会被实例继承.

可以通过extends实现类与类之间的继承

super 方法

子类必须在 constructor 方法中调用 super 方法,否则使用this就会报错。 这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例,因此super()在这里相当于A.prototype.constructor.call(this),所以super指向的是A的原型对象(A的prototype)

super可以作为函数和对象进行调用

- 作为函数则表示父类的构造函数

- 作为对象表示父类的原型对象而不是父类本身,只能调用到构造器里的属性和方法.

可以通过getter和setter监听存取值的行为

静态方法和静态属性

静态方法可以跟非静态方法重名

父类静态方法可以被子类继承,但不能被实例继承 super在静态方法之中指向父类,在普通方法之中指向父类的原型对象. B继承A,需要调用super(),才能使用this

AST树形结构

AST树形结构,就是把js代码按照特定的规则,变成特殊对象,以至于在更改js逻辑的时候,其实就是修改了AST对象的属性值,然后再变成js源码,转换规则可以自定义,也可以使用社区规范

promise和async await

Promise:
三种状态,不可逆,两个参数,成功回调,失败回调.then也是这两个参数

.then不传值,则为undefined,传普通数据,则为下一个函数的参数,传promise对象,则把异步结果作为参数传递

如果不设置失败回调,错误无法抛出,一般在最后设置一个.catch用来错误捕获

    Promise.resolve() 返回一个成功Promise,reject相反
    Promise.all(),等待所有结束,有一个失败,就算失败
    Promise.race(),等待最快的返回结果,最快的是什么,race就是什么
    Promise.finally(),表示不管结果如何都会执行该函数
复制代码
async await:
函数名前面加async,表明这是一个异步函数,函数里面await表示等待执行结果再执行代码
复制代码

闭包

闭包的理解:

闭包可以让一个函数访问另外一个函数中的变量,并且不会随着函数执行完毕而回收, 子函数可以直接访问父函数的变量,反之则不行,称之为作用域链.

实际案例:

防抖节流函数, 模块化,

Common.js和ES6 Module

一 . common.js是模块化 , 每个模块都是单独的作用域

利用require方法读取module.export导出的对象.但因为require是同步的 , script标签天生异步的 , 所以需要处理方案

AMD方案:

异步模块定义 , 借助require.js解决了多个js文件依赖的关系,以及js加载时浏览器会停止运行两个问题.(异步加载 ,解决浏览器卡顿 , 指定回调函数 , 一号位没加载完不会加载二号位,解决多文件依赖)

CMD方案:

通用模块定义 , 借助sea.js , 推崇一个模块一个文件.

关系和区别

都是解决的同样的问题,只是方法略有不同,AMD推崇依赖前置,定义的时候就要声明 , CMD推崇就近依赖,用到的时候才加载
AMD用户体验好,因为没有延迟,依赖模块提前执行了,CMD性能好,因为只有用户需要的时候才执行

二. ES6 Modules

是js自带的语法,是声明式的代码集合(集合里面保存可以导出的变量以及导出数据的内存地址)

三. 关系和区别

写法区分:

//导入
common.js:let a = require()
ES6      :import {a} from ''./index.js

//导出 
common.js: module.export
ES6      : export default 或 export const  mode = {};
复制代码
  • ES6是在代码正式运行之前(编译阶段)执行, 而CommonJS必须在运行时执行
  • es6一般在浏览器环境 , common.js一般在node环境

End

文章分类
前端
文章标签