let、const、var的区别
let、const、var 的区别
块级作用域: 块作用域由 { }包括,let 和 const 具有块级作用域,var 不存在块级作用域。块级作用域解决了 ES5 中的两个问题:
内层变量可能覆盖外层变量用来计数的循环变量泄露为全局变量
变量提升: var 存在变量提升,let 和 const 不存在变量提升,即在变量只能在声明之后使用,否在会报错。
给全局添加属性: 浏览器的全局对象是 window,Node 的全局对象是 global。var 声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是 let 和 const 不会。
重复声明: var 声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const 和 let 不允许重复声明变量。
暂时性死区: 在使用 let、const 命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用 var 声明的变量不存在暂时性死区。
初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而 const 声明变量必须设置初始值。
指针指向: let 和 const 都是 ...
async语法怎么捕获异常
async 语法怎么捕获异常
async 函数内部的异常可以通过 *.catch()*或者 try/catch 来捕获,区别是try/catch 能捕获所有异常,try 语句抛出错误后会执行 catch 语句,try 语句内后面的内容不会执行catch()只能捕获异步方法中 reject 错误,并且 catch 语句之后的语句会继续执行
123456789101112131415161718192021async函数错误捕获,以登录功能为例 async function getCatch () { await new Promise(function (resolve, reject) { reject(new Error('登录失败')) }).catch(error => { console.log(error) // .catch()能捕获到错误信息 }) console.log('登录成功 ...
async/await对比Promise的优势
async/await对比Promise的优势
代码读起来更加同步,Promise虽然摆脱了回调地狱,但是then的链式调⽤也会带来额外的阅读负担
Promise传递中间值⾮常麻烦,⽽async/await⼏乎是同步的写法,⾮常优雅
错误处理友好,async/await可以⽤成熟的try/catch,Promise的错误捕获⾮常冗余
调试友好,Promise的调试很差,由于没有代码块,你不能在⼀个返回表达式的箭头函数中设置断点,如果你在⼀个.then代码块中使⽤调试器的步进(step-over)功能,调试器并不会进⼊后续的.then代码块,因为调试器只能跟踪同步代码的每⼀步。
await的使用注意点
await的使用注意点
await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。
多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
await命令只能用在async函数之中,如果用在普通函数,就会报错。
async 函数可以保留运行堆栈。
如何用await让程序停顿指定的时间(休眠效果)
如何用await让程序停顿指定的时间(休眠效果)
JavaScript 一直没有休眠的语法,但是借助await命令就可以让程序停顿指定的时间
12345678910111213141516function sleep(interval) { return new Promise(resolve => { setTimeout(resolve, interval); })}// 用法async function one2FiveInAsync() { for(let i = 1; i <= 5; i++) { console.log(i); await sleep(1000); }}one2FiveInAsync();
await 到底在等待什么?
await 在等什么
await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,就是没有特殊限定)。await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。
await 表达式的运算结果取决于它等的是什么。
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
异步编程的实现方式?
异步编程的实现方式?**JavaScript中的异步机制可以分为以下几种:
回调函数 的方式,使用回调函数的方式有一个缺点是,多个回调函数嵌套的时候会造成回调函数地狱,上下两层的回调函数间的代码耦合度太高,不利于代码的可维护。Promise 的方式,使用 Promise 的方式可以将嵌套的回调函数作为链式调用。但是使用这种方法,有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确。generator 的方式,它可以在函数的执行过程中,将函数的执行权转移出去,在函数外部还可以将执行权转移回来。当遇到异步函数执行的时候,将函数执行权转移出去,当异步函数执行完毕时再将执行权给转移回来。因此在 generator 内部对于异步操作的方式,可以以同步的顺序来书写。使用这种方式需要考虑的问题是何时将函数的控制权转移回来,因此需要有一个自动执行 generator 的机制,比如说 co 模块等方式来实现 generator 的自动执行。async 函数 的方式,async 函数是 generator 和 promise 实现的一个自动执行的语法糖,它内部自带执行器,当函数内部执行到一个 ...
class继承
class继承关键:class里的extends和super关键字,继承效果与寄生组合继承一样
12345678910111213141516171819202122 class Father { constructor(name) { this.name = name } showName() { console.log(this.name); } } class Son extends Father { // 子类通过extends继承父类 constructor(name, age) { super(name) // 调用父类里的constructor函数,等同于Father.call(this,name) this.age = age } showAge() { console.log(this.age); ...
混入继承
混入继承关键:利用Object.assign的方法多个父类函数的原型拷贝给子类原型
12345678910111213141516171819202122232425 function Father(name) { this.name = name } Father.prototype.showName = function () { console.log(this.name); } function Mather(color) { this.color = color } Mather.prototype.showColor = function () { console.log(this.color); } function Son(name, color, age) { // 调用两个父类函数 Father.call(this, name) Mather.call ...
寄生组合继承
寄生组合继承关键:原型式继承 + 构造函数继承
Js 最佳的继承方式,只调用了一次父类构造函数
12345678910111213141516171819 function Father(name) { this.name = name this.say = function () { console.log('hello,world'); } } Father.prototype.showName = function () { console.log(this.name); } function Son(name, age) { Father.call(this, name) this.age = age } Son.prototype = Object.create(Father.prototype) // Object.create方法返回一个对象,它的隐式原型指向 ...