理解javascript构造函数继承

来源:互联网 发布:视在功率的算法 编辑:程序博客网 时间:2024/04/23 15:27

对象之间的继承有以下几个方法:

  • 用call和apply(不推荐单独使用,定义在prototype中的属性和方法不能继承)

  • prototype模式(注意prototype需要先继承后定义)

    • 传统prototype模式(推荐,关键点是Child.prototype = new Parent.prototype以及重新改变Child.prototype.constructor)

    • 利用空对象间接继承(只继承prototype中的属性,关键点在于利用一个空的构造函数当中介)

  • 拷贝继承(不推荐单独使用,for循环逐一拷贝)

以上推荐使用传统prototype模式以及call和apply与拷贝继承相配合的模式

用call和apply

function Chinese() {    this.nationality = "Chinese";}function Person(name, age) {    Chinese.apply(this); //这里改变了Chinese中this的指向    this.name = name;    this.age = age;}var p1 = new Person("Oli", 18);console.log(p1.nationality); //Chinese

传统prototype模式

function Chinese() {    this.nationality = "Chinese";}function Person(name, age) {    this.name = name;    this.age = age;}Person.prototype = new Chinese(); //这里因为在prototype中使用了new,则会指向Chineseconsole.log(Person.prototype.constructor); //Chinese(){}Person.prototype.constructor = Person; //这里需要把constructor构造函数重新改为Personconsole.log(Person.prototype.constructor); //Person(){}var p1 = new Person("Oli", 18);console.log(p1.nationality); //Chinese

需要注意的是:在继承中,如果替换了prototype,那么新的prototype必须修改constructor属性,将这个属性指回到原来的构造函数。

利用空对象间接继承

function Chinese() {}Chinese.prototype.nationality = "Chinese";function Person(name, age) {    this.name = name;    this.age = age;}function F(){}; //空对象几乎不占用内存F.prototype = Chinese.prototype;Person.prototype = new F();Person.prototype.constructor = Person;Person.prototype.sayName = function() { //Person的prototype中的方法和属性需要在继承之后定义    console.log(this.name);};var p1 = new Person("Oli", 18);console.log(p1.nationality); //Chinesep1.sayName(); //Oli

可以将该方法定义为函数:

function extend(Child, Parent) {    var F = function() {};    F.prototype = Parent.prototype;    Child.prototype = new F();    Child.prototype.constructor = Child;    Child.uber = Parent.prototype; //用于访问父对象的prototype,可用可不用}

举例:

function extend(Child, Parent) {    var F = function() {};    F.prototype = Parent.prototype;    Child.prototype = new F();    Child.prototype.constructor = Child;    Child.uber = Parent.prototype;}function Chinese() {}Chinese.prototype.nationality = "Chinese";function Person(name, age) {    this.name = name;    this.age = age;}extend(Person, Chinese);Person.prototype.sayName = function() {    console.log(this.name);};var p1 = new Person("Oli", 18);console.log(p1.nationality); //Chinesep1.sayName(); //Oli

拷贝继承

使用下面的函数逐一将prototype的属性和函数拷贝到对象中:

function extend(Child, Parent) {        var p = Parent.prototype;        var c = Child.prototype;        for (var i in p) {              c[i] = p[i];          }        c.uber = p;  }

不需要先继承后定义


传统prototype模式继承(例子)

function Parent() {    this.name = "thisIsName";}Parent.prototype.sayName = function() {    return this.name;};function Child() {    this.age = "thisIsAge";}Child.prototype = new Parent();Child.prototype.constructor = Child;Child.prototype.sayAge = function() {    return this.age;};var c = new Child();console.log(c.name);console.log(c.age);console.log(c.sayName());console.log(c.sayAge());

call和apply与拷贝继承相配合(例子)

function extend(C, P) {    var p = P.prototype;    var c = C.prototype;    for(var i in p){        c[i] = p[i];    }    c.uber = p;}function Parent() {    this.name = "thisIsName";}Parent.prototype.sayName = function() {    return this.name;};function Child() {    Parent.apply(this); //继承构造函数内的属性和方法    this.age = "thisIsAge";}Child.prototype.sayAge = function() {    return this.age;};extend(Child, Parent); //不需要先继承后定义var c = new Child();console.log(c.name);console.log(c.age);console.log(c.sayName());console.log(c.sayAge());

源引:https://segmentfault.com/a/1190000004906911

0 0
原创粉丝点击