js 深入图说

124 阅读2分钟

1 原型链

原型链就是按照 proto 寻找,直到 Object。instanceof 原理也是根据原型链判断的; p.proto==P.prototype=>P.prototype.proto==object.prototype=>object.prototype.proto==null

p instanceof P // true
p instanceof Object // true

2 promise.race()

这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:

//请求某个图片资源
function requestImg(){
    return new Promise((resolve,reject)=>{
       var img=new Image()
       img.src='xxx';
       img.onload=function(){
           resolve(img)
       } 
    })
    
}

//延时函数,用于给请求计时
function timeout(){
    return new Promise((resolve,reject)=>{
       setTimeOut(()=>{
           reject('图片请求超时!')
       },5000)
    }
}

Promise.race([requestImg(),timeout()]).then((res)=>{
    console.log(res)
}).catch((reason)=>{
     console.log(reason)
})

requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。运行结果如下:

3 promise.all()

4 ES5继承和ES6继承的区别

  • ES5 继承是实质上是先创建子类的实例对象,然后再将父类的方法添加到this上,Parent.call(this),然后再把原型链继承
  • ES6 继承的实质是先创建父类的实例对象,所以必须先调用父类的super()方法,才能使用this关键字,否则报错;
class Parent {
    constructor() {
      this.name = 'parent';
    }
    say() {
      console.log('say');
    }
}
class Child2 extends Parent {
    constructor(age) {
      super();
      this.age = age;
    }
}
var c2 = new Child2(12);
console.log(c2.name, c2.age); //输出parent
c2.say(); //输出say
console.log(c2.constructor); //输出function Child(age) {Parent.call(this);this.age = age;}
console.log(new Parent().constructor); //输出Parent() {this.name = 'parent';this.arr = [1,2,3,4];}

5

var a = {};

a == true // -> ?
a == false // -> ?

{} 等于true还是false答案是两个都为false 因为 a.toString() -> '[object Object]' -> NaN

6 async await

async 和 await 可以说是异步终极解决方案了,相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码,毕竟写一大堆 then 也很恶心,并且也能优雅地解决回调地狱问题。async和await的用法