最新最热

每日必应图片接口

JS实现继承的几种方式

JS实现继承的几种方式先定义一个父类fuctioFather(ame){//属性thi.ame=ame||'father'//实例方法thi.ayName=fuctio(){coole.log(thi.ame)}thi.color=['lue']}//原型方法Father.rototye.age=20Father.rototye.ayAge=fuctio(){coole.log(thi.age)}1.原型链继承将父类的实例作为子类的原型fuctioSo(ame){thi.ame=ame|'So'}So.rototye=ewFather()let1=ewSo()coole.log(1.ame)//Socoole.log(1.age)//20优点:简单,易于实现父类新增原型方法、原型属性,子类都能访问到缺点:无法实现多继承,因为原型一次只能被一个实例更改要想为子类新增属性和方法,必须要在ewFather()这样的语句之后执行,不能放到构造器中来自原型对象的所有属性被所有实例共享创建子类实例时,无法向父构造函数传参2.构造继承使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)fuctioSo(ame){Father.call(thi)thi.ame=ame||'o'}let=ewSo('So')coole.log(.ame)//So//.ayAge()抛出错误,无法继承父类原型方法//.ayName()Socoole.log(.age)//udefied(无法继承父类原型方法)优点:解决了原型链继承中子类实例共享父类引用属性的问题创建子类实例时,可以向父类传递参数可以实现多继承(call多个父类对象)缺点:实例并不是父类的实例,只是子类的实例只能继承父类的实例属性和方法,不能继承原型属性/方法无法实现函数复用,每个子类都有父类实例函数的副本,影响性能3.组合继承将原型链和借用构造函数的技术组合到一块。使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承fuctioSo(ame){//第一次调用父类构造器子类实例增加父类实例Father.call(thi,quot我是传给父类的参数quot)thi.ame=ame||quotoquot}//经过ew运算符第二次调用父类构造器子类原型也增加了父类实例So.rototye=ewFather()let=ewSo(quotoquot)coole.log(.ame)//o.ayAge()//18.ayName()//ocoole.log(.age)//18coole.log(itaceofFather)//truecoole.log(itaceofSo)//truecoole.log(.cotructor===Father)//truecoole.log(.cotructor===So)//fale优点:弥补了构造继承的缺点,现在既可以继承实例的属性和方法,也可以继承原型的属性和方法既是子类的实例,也是父类的实例可以向父类传递参数函数可以复用缺点:调用了两次父类构造函数,生成了两份实例cotructor指向问题4.实例继承为父类实例添加新特征,作为子类实例返回fuctioSo(ame){letf=ewFather('传给父类的参数')f.ame=ame||'o'returf}let=ewSo(quotoquot)//或者直接调用子类构造函数let=So(quotoquot)coole.log(.ame)//o.ayAge()//18.ayName()//ocoole.log(.age)//18coole.log(itaceofFather)//truecoole.log(itaceofSo)//falecoole.log(.cotructor===Father)//truecoole.log(.cotructor===So)//fale优点:不限制调用方式,不管是ew子类()还是子类(),返回的对象具有相同的效果缺点:实例是父类的实例,不是子类的实例不支持多继承5.拷贝继承对父类实例中的的方法与属性拷贝给子类的原型fuctioSo(ame){letf=ewFather(quot传给父类的参数quot)for(letkif){So.rototye[k]=f[k]}So.rototye.ame=ame}let=ewSo(quotoquot)coole.log(.ame)//o.ayAge()//18.ayName()//ocoole.log(.age)//18coole.log(itaceofFather)//falecoole.log(itaceofSo)//truecoole.log(.cotructor===Father)//falecoole.log(.cotructor===So)//true优点:支持多继承缺点:效率低,性能差,占用内存高(因为需要拷贝父类属性)无法获取父类不可枚举的方法(不可枚举的方法,不能使用for-i访问到)6.寄生组合继承通过寄生方式,砍掉父类的实例属性,避免了组合继承生成两份实例的缺点fuctioSo(ame){Father.call(thi)thi.ame=ame||quotoquot}//方法一自己动手创建一个中间类//(fuctio(){//letNoeFu=fuctio(){}//NoeFu.rototye=Father.rototye//So.rototye=ewNoeFu()//So.rototye.cotructor=So//})()//方法二直接借用Oject.create()方法So.rototye=Oject.create(Father.rototye)//修复构造函数指向So.rototye.cotructor=Solet=ewSo(quotoquot)coole.log(.ame)//o.ayAge()//18.ayName()//ocoole.log(.age)//18coole.log(itaceofFather)//truecoole.log(itaceofSo)//truecoole.log(.cotructor===Father)//falecoole.log(.cotructor===So)//true优点:比较完美(j实现继承首选方式)缺点:1.实现起来较为复杂(可通过Oject.create简化)7.e6--Cla继承使用exted表明继承自哪个父类,并且在子类构造函数中必须调用uerclaSoextedFather{cotructor(ame){uer(ame)thi.ame=ame||quotoquot}}let=ewSo(quotoquot)coole.log(.ame)//o.ayAge()//18.ayName()//ocoole.log(.age)//18coole.log(itaceofFather)//truecoole.log(itaceofSo)//truecoole.log(.cotructor===Father)//falecoole.log(.cotructor===So)//tru

JavaScript 中 call()、apply()、bind() 的用法

JavaScrit中call()、aly()、id()的用法其实是一个很简单的东西,认真看10分钟就从一脸懵B到完全理解!先看明白下面:例1varame='小王',age=17varoj={ame:'小张',ojAge:thi.age,myFu:()=gt{coole.log(`${thi.ame}年龄${thi.age}`)}}oj.ojAge//17oj.myFu()//小张年龄udefied例2varfav='盲僧'fuctiohow(){coole.log(thi.fav)}how()//盲僧比较一下两者thi的差别,第一个打印里的thi指向oj,第二个全局声明的how()函数thi是widow1.call()、aly()、id()都是用来定义thi这个对象的如:varame='小王',age=17varoj={ame:'小张',ojAge:thi.age,myFu:()=gt{coole.log(`${thi.ame}年龄${thi.age}`)}}vard={ame:'德玛',age:99}oj.myFu.call(d);//德玛年龄99oj.myFu.aly(d)//德玛年龄99oj.myFu.id(d)()//德玛年龄99以上出了id方法后面多了个()外,结果返回都一致~由此得出结论,id返回的是一个新的函数,你必须调用它才会被执行2.对比call、id、aly传参情况下varame='小王',age=17varoj={ame:'小张',ojAge:thi.age,myFu:(form,t)=gt{coole.log(`${thi.ame}年龄${thi.age},来自${form},去往${t}`)}}vard={ame:'德玛',age:99}oj.myFu.call(d,'成都','上海')oj.myFu.aly(d,['成都','上海'])oj.myFu.id(d,'成都','上海')()oj.myFu.id(d,['成都','上海'])()微妙的差距!从上面四个结果不难看出:call、id、aly这三个函数的第一个参数都是thi的指向对象,第二个参数差别就来了:call的参数是直接放进去的,第二第三第个参数全都用逗号分隔,直接放到后面oj.myFu.call(d,'成都',...,'trig')。aly的所有参数都必须放在一个数组里面传进去oj.myFu.aly(d,['成都',...,'trig'])id除了返回是函数以外,它的参数和call一样当然,三者的参数不限定是trig类型,允许是各种类型,包括函数、oject等等!