手机版

JavaScript继承学习笔记【初学者必读】

时间:2021-10-31 来源:互联网 编辑:宝哥软件园 浏览:

作为一种面向对象的语言(JS是基于对象的),需要实现继承。但是由于JavaScript本身没有类的概念,所以并不像真正的面向对象编程语言那样通过类实现继承,而是可以通过其他方法实现继承。实现继承的方法有很多,以下只是其中的几种。

1.原型链的继承。

函数Person() {//的继承函数叫做supertype(父类,基类)this.name='牧牧';this.age=' 18} person . prototype . name=' susu ';//当属性名称相同时,需要接近原则。首先,查看实例,如果找不到functionworker(),则在原型中查找它。{//继承的函数称为subtype(子类,派生类)this.job=' student} worker . prototype=new Person();//被原型链继承,超类型实例化的对象实例赋给子类的原型属性var p2=new Worker();console . log(p2 . name);控制台日志(对象的p2实例);//true所有构造函数都是从Object继承的。继承的要点是:worker . prototype=new Person();使Worker的原型成为Person的实例,并通过原型链继承它。

注意:使用原型链实现继承时,不能使用对象文字创建原型方法,因为这样会破坏关系,重写原型链。

原型链继承问题:

1.当存在引用共享问题时,它们仍然共享一个空间,子类会影响父类。

函数Person() { this.bodys=['eye ',' foot '];}函数Worker(){ } Worker . prototype=new Person();var p1=新Worker();p1.bodys.push('手');var p2=新Worker();console . log(P1 . bods);console . log(p2 . bods);

2.创建子类型的实例时,不能像传递超类型的构造函数那样传递参数。

那么如何解决原型链的两个问题呢?那就继续看看下面的继承方法吧~

2.借用构造函数继承(也称为模拟对象、伪造对象或经典继承)。

函数Person(姓名、年龄){ this.name=namethis.age=年龄;this.bodys=['eye ',' foot '];} person . prototype . show name=function(){ console . log(this . name);}函数Worker(姓名、年龄、工作){ Person.call(this,姓名、年龄);this.job=job//子类添加属性} var p1=new Worker('牧牧',' 18 ','学生');p1.bodys.push('手');var p2=新Worker();console . log(P1 . name);console . log(p2 . bods);console . log(P1 . show name());

简单分析下,以上借用构造函数的原则如下:Person.call(this,name,age);此代码调用父构造函数,继承父属性,并在执行函数时使用调用方法调用Person构造函数来更改此属性。来自这个新的Worker对象构造器的一个伪装方法:将Worker传递给上面的人。

当引用类型放在构造函数中时,它不会被共享,因此p2不受影响。

这里利用构造函数继承解决了原型链不能传递参数和引用类型共享的问题。

小知识:调用()和apply()方法可以改变函数执行的范围,简单来说就是改变函数中由此指向的内容。

call()和apply()都接受两个参数:第一个是函数运行的范围,另一个是传递的参数。

调用应用和调用应用的区别在于参数不同。CALL中的参数必须逐个枚举。APPLY中的参数必须是数组或参数对象。

那么问题来了:为什么p1.showName()的结果是错的?- .这里还发现了一个借用构造函数的问题。

注意:由于所有的方法都放在构造函数中,所以每次实例化的时候,都会分配内存空间浪费资源,所以我们通常把方法放在原型中,把属性放在构造函数中。

借用构造函数继承问题:

因为借用的构造函数只能继承构造函数中的属性和方法,而超类型的原型中定义的方法对于子类是不可见的,所以相当于没有原型。因此,所有方法只能在构造函数中定义,因此没有函数重用。

那么如何解决借用构造函数带来的问题呢?这取决于下面的继承方法。

三.组合继承(伪经典继承)

函数Person(姓名、年龄){ this.name=namethis.age=年龄;} person . prototype . show name=function(){ console . log(this . name);}函数Worker(姓名、年龄、工作){ Person.call(this,姓名、年龄);//借用构造函数this.job=job} worker . prototype=new Person();//原型链继承var p1=new Worker('牧牧',' 18 ','学生');console . log(P1 . age);P1 . show name();组合继承:将原型链与借用的构造函数相结合。

思路:利用原型链继承原型上的属性和方法,利用构造函数继承实例属性。

上面的例子Person.call(这个,名字,年龄);借用的构造函数继承属性。

worker . prototype=new Person();原型链继承方法,避免它们的缺点,结合它们的优点,成为最常用的继承模式。

组合遗传的问题:

调用超类型构造函数两次,一次在创建子类型原型时,一次在子类型的构造函数中。

为了解决这个问题,我们需要使用寄生组合遗传。

四.原型继承

函数对象(proto){ function F()} { F . prototype=proto;返回新的F();} var person={ name: '牧牧',friends 3360['夏夏','苏苏']};var other PeRsoN=object(person);另一个人。朋友。推(文);var yetotherperson=object(person);另一个人。朋友。推('天');console . log(person . friends);//['夏夏','苏苏','文','田']控制台。__proto__)//Object {name: '牧牧',在friends 3360 Array[4]的简单分析下,函数对象(proto)是一个临时传递函数,其中参数proto表示一个要传入的对象,f()构造函数是一个临时创建的对象,用来存储传入的对象,f . proto=proto;将对象实例赋给F构造函数的原型对象,最后返回传递对象的对象实例。原型继承仍然共享引用类型的属性。

五、寄生演替

//临时传递函数function object(proto){ function f(){ } f . prototype=proto;返回新的F();}//寄生函数create(proto){ var f=object(proto);f . love=function(){ return this . name;}返回f;} var person={ name: '牧牧',friends 3360['夏夏','苏苏']};var other PeRsoN=create(PeRsoN);console . log(other person . love());寄生组合继承六。寄生组合遗传。

函数对象(proto){ function F()} { F . prototype=proto;返回新的F();}//寄生函数create (person,worker) {var f=object (person。原型);//创建一个对象f.constructor=Worker//调整原型构造指针,增强对象worker . prototype=f;//指定对象}函数人(姓名、年龄){this。name=namethis.age=年龄;} person . prototype . show name=function(){ console . log(this . name);}函数Worker(姓名、年龄、工作){ Person.call(this,姓名、年龄);this.job=job}创建(人员、工人);//寄生组合继承var p1=new Person('牧牧',' 18 ','学生');P1 . show name();这种方法也是目前实现继承最完善、最理想的方法。

以上JavaScript继承学习笔记【初学者必读】是边肖分享的全部内容,希望能给大家一个参考和支持。

版权声明:JavaScript继承学习笔记【初学者必读】是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。