你不可不知的JS面试题(第二期)

1、什么是继承?

子类可以使用父类的所有功能,并且对功能进行扩展。

  • 新增方法

  • 改用方法

(1)、ES6使用extends子类继承父类的方法。

1 // 父类 2    class A{ 3        constructor(name){ 4            this.name= name; 5        } 6        getName () { 7            return this.name; 8        } 9    }; 10    // 子类继承 11    class B extends A { 12        constructor(name){ 13           super(name) //  记得用super调用父类的构造方法! 14        } 15        getName(){ 16            const name = super.getName(); 17            return name; 18        } 19    } 20     21    var b = new B('2'); 22    console.log(b.getName()); //2

(2)、ES5的继承方法:

1// 父类 2function P(name) { 3    this.name = name; 4} 5// 父类方法 6P.prototype.get=function(){ 7    return this.name; 8} 9// 子类 10function C(name){ 11    P.call(this,name); 12} 13// 封装继承。也就是C.prototype.__proto__ = P.prototype 14function I(Pfn,Cfn){ 15    var prototype = Object.create(Pfn.prototype); 16    prototype.constructor = Cfn; 17    Cfn.prototype = prototype; 18} 19// 调用继承方法,并传入参数 20I(P,C); 21 22 23var c = new C('maomin'); 24console.log(c.get()); // maomin 25

(3)、ES3实现继承

使用ES3实现继承无非是替代了Object.create(Pfn.prototype),我们先来看下

大家知道我们封装的I方法是原理是C.prototype.__proto__ = P.prototype。但是我们不推荐这样,因为__proto__是浏览器内置的属性,并不是JS内置的,所以不推荐这样做。我们来封装一个方法来替代Object.create(Pfn.prototype)

1function objectCreate (o) { 2 function P1() {} 3 P1.prototype = o; 4 return new P1(); 5} 6

完整代码:

1 // 父类 2    function P(name) { 3        this.name = name; 4    } 5   // 父类方法 6    P.prototype.get = function () { 7        return this.name; 8    } 9 // 子类 10    function C(name) { 11        P.call(this, name); 12    } 13 // 封装object.create() 14    function objectCreate(o) { 15        function P1() {} 16        P1.prototype = o; 17        return new P1(); 18    } 19    // 封装继承 20    //C.prototype.__proto__ = P.prototype; 21    function I(Pfn, Cfn) { 22        var prototype = objectCreate(Pfn.prototype);  23        prototype.constructor = Cfn; 24        Cfn.prototype = prototype; 25    } 26     27    // 调用继承方法,并传入参数 28    I(P, C); 29     30    var c = new C('maomin'); 31    console.log(c.get()); // maomin

(4)、新增API

新增ES6方法 Reflect.setPrototypeOf()可以实现C.prototype.__proto__ = P.prototype

1 function A(name){this.name=name} 2   A.prototype.get=function () {return this.name} 3   function B (name) {A.call(this,name)} 4   Reflect.setPrototypeOf(B.prototype,A.prototype); 5   var b = new B('maomin'); 6   console.log(b.get()); //maomin

2、关于Promise,你知道什么?

(1)、Promise是什么?

Promise是异步编程的一种解决方案,同时他有很多规范,如Promise/A,Promise/B,Promise/D以及Promise/A的升级版Promise/A+,而ES6中采用了Promise/A+规范。

(2)、Promise的作用是什么?
  • 解决“回调地狱”问题

  • 解决并发请求问题

  • 解决异步编程代码执行顺序理解困难的问题

① 解决“回调地狱”问题

我们先看下面代码,看到会不会觉得太冗余了啊。如果代码多的话,很难维护。

1 let count = 0; 2    setTimeout(() => { 3        count++; 4        console.log(`地狱${count}`); 5        setTimeout(() => { 6            count++; 7            console.log(`地狱${count}`); 8            setTimeout(() => { 9                 count++; 10                 console.log(`地狱${count}`); 11            }, 500); 12        }, 500); 13    }, 500);

我们可以看到使用Promise让它永远在第一层,打印出 我还在人间 ,而不会越来越深。

1 let count = 0; 2    new Promise(resolve =>{ 3        setTimeout(() => { 4             count++; 5             resolve(); 6        }, 500); 7    }).then(()=>{ 8        return new Promise(resolve=>{ 9            setTimeout(() => { 10                 count++; 11                 resolve(); 12            }, 500); 13        }) 14    }).then(()=>{ 15        console.log('我还在人间') 16    })

② 解决并发请求问题可以在执行result1result2 结束后再执行下面的代码

1const result1 = fetch('/getName'); 2const result2 = fetch('/getAge'); 3Promise.all([result1,result2]).then(()=>{ 4// 执行 5}) 6

③解决异步编程代码执行顺序理解困难的问题我们先看下这个场景,get方法是异步的方法,在执行getInfo方法时,并不会先执行get方法,而是先打印出我是getInfo方法

1function get() { 2    setTimeout(() => { 3        console.log('执行get方法'); 4    }, 1000); 5} 6function getInfo() { 7    get(); 8    console.log('我是getInfo方法'); 9} 10getInfo(); 11// 我是getInfo方法 12// 执行get方法 13

那么,我们使用Promise来解决异步,同时我们使用了ES6asyncawait来等待get方法执行完再执行下面的代码。

1function get() { 2    return new Promise((resolve)=>{ 3        setTimeout(() => { 4            console.log('执行get方法'); 5            resolve(); 6        }, 1000); 7    }) 8} 9async function getInfo() { 10    await get(); 11    console.log('我是getInfo方法'); 12} 13getInfo(); 14// 执行get方法 15// 我是getInfo方法 16

3、如何实现Promise?

我们先来了解Promise

  • Promise包含then方法

  • then方法的两个参数resolvereject

  • Promise包含3个状态:pending(等待态)resolved(成功态)rejected(失败态)

返回成功resolve:

1new Promise((resolve,reject)=>{ 2    setTimeout(() => { 3        resolve('success!') //返回成功状态 4    }, 1000); 5}).then((v)=>{ 6    console.log(v); 7},(e)=>{ 8    console.log(e); 9}) 10

返回错误reject:

1new Promise((resolve,reject)=>{ 2    setTimeout(() => { 3        reject('error!') //返回失败状态 4    }, 1000); 5}).then((v)=>{ 6    console.log(v); 7},(e)=>{ 8    console.log(e); 9}) 10

好了,我们来实现一下,封装一个Promise

1 function myPromise(fn) { 2        this.status = 'pending'; // 初始化等待状态 3        this.data = undefined; // 初始化一个存储变量 4        this.resolvedCallback = []; //成功方法保存 5        this.rejectedCallback = []; // 失败方法保存 6         7        const resolve = (val) => { 8            if (this.status === 'pending') { 9                this.status = 'resolved'; 10                this.data = val; 11                this.resolvedCallback.forEach(fu => fu.call(this)); 12            } 13        } 14         15        const reject = (val) => { 16            if (this.status === 'pending') { 17                this.status = 'rejected'; 18                this.data = val; 19                this.rejectedCallback.forEach(fu => fu.call(this)); 20            } 21        } 22         23        fn(resolve, reject); 24    } 25    // 封装then方法 26    myPromise.prototype.then = function (onResolved, onRejected) { 27        return new myPromise((resolve, reject) => { 28         29            const resolvedCallback = () => { 30                const result = onResolved(this.data); 31                if (result instanceof myPromise) { 32                    result.then(resolve, reject); 33                } else { 34                    resolve(result); 35                } 36            } 37            const rejectedCallback = () => { 38                const result = onRejected(this.data); 39                if (result instanceof myPromise) { 40                    result.then(resolve, reject); 41                } else { 42                    resolve(result); 43                } 44            } 45             46            if (this.status === 'resolved') { 47                resolvedCallback(); 48            } else if (this.status === 'rejected') { 49                rejectedCallback(); 50            } else { // this.status === 'pending' 51                this.resolvedCallback.push(resolvedCallback); 52                this.rejectedCallback.push(rejectedCallback); 53            } 54             55        }) 56 57    } 58    // 使用 59    new myPromise((resolve, reject) => { 60        setTimeout(() => { 61            resolve('success!'); 62        }, 1000); 63    }).then((v) => { 64        console.log(v) 65    }, (e) => { 66        console.log(e) 67    }).then(() => { 68        console.log('1') 69    })

下一期更新 请关注 第三期


作者:Vam的金豆之路

主要领域:前端开发

我的微信:maomin9761

微信公众号:前端历劫之路


本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/0vHHCviZSQfaJRX7mZkqNQ,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

js继承的几种方式

1.原型链继承原型链继承:想要继承,就必须要提供父类(继承谁,提供继承的属性)//父级functionPerson(name)//给构造函数添加参数this.namename;this.age10;this.sumfunction()console.log(this.name)//原