let var const 区别
let 块级作用域 存在暂时性死区 会改变指针指向
var 全局作用域 有变量提升 会添加全局属性 可以 重复声明变量名称 会改变指针的指向
const 块级作用域 存在暂时性死区 必须设置初始值
(1)块级作用域: 块作用域由 { }包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中的两个问题:
- 内层变量可能覆盖外层变量
- 用来计数的循环变量泄露为全局变量
(2)变量提升: var存在变量提升,let和const不存在变量提升,即在变量只能在声明之后使用,否在会报错。
(3)给全局添加属性: 浏览器的全局对象是window,Node的全局对象是global。var声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是let和const不会。
(4)重复声明: var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const和let不允许重复声明变量。
(5)暂时性死区: 在使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区。
(6)初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值。
(7)指针指向: let和const都是ES6新增的用于创建变量的语法。 let创建的变量是可以更改指针指向(可以重新赋值)。但const声明的变量是不允许改变指针的指向。
es6解构赋值
- 解构赋值:主要用来从数组和对象中提取值,对变量进行赋值。
[]
:是专门解构数组使用的{}
:是专门解构对象使用的
解构对象:
对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
如果变量与属性不同名,需要先匹配属性名,在定义变量。
对象让我们能够创建通过键来存储数据项的单个实体。
数组则让我们能够将数据收集到一个有序的集合中。
但是,当我们把它们传递给函数时,函数可能不需要整个对象/数组。它可能只需要对象/数组的一部分。
解构赋值 是一种特殊的语法,它使我们可以将数组或对象“拆包”至一系列变量中,因为有时这样更方便。解构操作对那些具有很多参数和默认值等的函数也很奏效.
箭头函数也普通函数的区别
1 写法不同
箭头函数使用箭头定义,普通函数中没有.
2 箭头函数不能用于构造函数
普通函数可以用于构造函数,以此创建对象实例
3 箭头函数中thsi的指向不同
箭头函数自身没有this, 它的this是父级普通函数的this.
在普通函数中,this总是指向调用它的对象或者 如果用构造函数 它指向被创建的对象实例
4 箭头函数不具有arguments对象
每个普通函数调用后都具有一个 arguments 对象, 用来储存实际传递的参数
但是箭头函数并没有此对象
5 箭头函数不能当Gnerator函数, 不能使用yield关键字
6 箭头函数不具有prototype原型对象
7 箭头函数不具有super
promise使用及实现
Promise对象是一个构造函数,用来生成promise实例。
Promise代表一个异步操作,有三种状态pending,resolved(异步操作成功由pending转为resolved)rejected(异步操作失败由pending转为rejected),一旦变成 resolve 或 reject两种状态后不会再更改。
resolve函数在异步操作成功后调用,将pending状态变为resolve,并将它的参数传递给回调函数;reject函数在异步操作失败时调用,将pending状态改为rejected,并将参数传递给回调函数。
注意:promise状态只能由pending=>fulfilled/rejected,一旦修改就不能再变。
Promise构造函数的原型有一个then方法,他接受两个函数作为参数,分别为resolved状态和rejected状态的回调函数,而这两个回调函数接受的参数分别是Promise实例中resolve和reject函数中的参数。
promise 实现
function Promise(fn){
var status='pending';
function successNotify(){
status='fulfilled';//状态变为fulfilled
toDoThen.apply(undefined,arguments);//执行回调
}
function failNotify(){
status="rejected";//状态变为rejected
toDoThen.apply(undefined,arguments);
}
function toDoThen(){
setTimeout(()=>{//保证回调是异步执行的
if(status==='fulfilled'){
for(let i=0;i<successArray.length;i++){
successArray[i].apply(undefined,arguments);//执行then里面的回调函数
}
}else if(status==='rejected'){
for(let i=0;i<failArray.length;i++){
failArray[i].apply(undefined,arguments);//执行then里面的回调函数
}
}
})
}
var successArray=[];
var failArray=[];
fn.call(undefined,successNotify,failNotify);
return{
then:function(successFn,failFn){
successArray.push(successFn);
failArray.push(failFn);
return undefined;//此处应该返回一个Promise
}
}
}
async await
async用于申明一个function是异步的;
而await则可以认为是 async await的简写形式,是等待一个异步方法执行完成的。
1、Async作为关键字放在函数前面,普通函数变成了异步函数
2、异步函数async函数调用,跟普通函数调用方式一样。在一个函数前面加上async,变成 async函数,异步函数,return:1,打印返回值,
3、返回的是promise成功的对象,
4、Async函数配合await关键字使用
Generator函数的理解和使用
ES6 提供的一种异步编程解决方案。
Generator函数就是一个封装的异步任务,或者说是异步任务的容器,异步操作需要暂停的地方,都用yield语句。
所谓“异步”,简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段
yield yield return
yield表达式就是暂停标志。
yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行。
es6新增数据类型
Sylbom 基本数据类型
是一个内置全局函数,可以生成独一无二的数据,解决同名冲突问题
Map 引用数据类型
Map对象保存键值对 key可以是任意值
set 引用数据类型
存储任何类型的唯一值 无序不重复 无论是原始值还是对象引用
weakSet
weakSet和Set一样,类似于数组,但里面只能存放内容不相同的值
weakSet内部只能存放对象类型的数据,不能存放其他类型的数据,会报错
在weakSet里引用了对象,垃圾回收机制不会考虑该对象的引用,若外面已经没有该对象的引用了,则垃圾回收机制会回收该对象,weakSet内部引用的该对象也会自动消失
所以weakSet内部的对象不适合被引用,也不允许遍历,因为有可能遍历的过程,内部的对象被垃圾回收机制回收了
一般用于
1 在weakSet中存储一些临时的对象,当外部该对象的引用消失了,weakSet内部该对象的引用也自动消失了,不用担心内存泄漏
2 存储一些DOM节点,这样就不用DOM节点从文档中移除时,产生内存泄漏
weakMap
和Map一样,它是键值对的集合,与JS中的对象不同的是Map和weakMap的键值可以是任意类型的数据,而JS中只能是字符串类型
weakMap只接受对象类型的数据作为键名
WeakMap是对于键名引用的对象弱引用,不是键值指向的对象,键值的引用依旧存在
weakMap键名指向的对象(注意:不是键值)不会对垃圾回收机制造成影响
所以当我们想要在对象上存储一些数据,但又不想造成对该对象的引用,就可以使用weakMap