您的位置:首页> 前端教程> JS教程
文章导航

JavaScript 继承

2018-12-20 22:24| 作者: admin| 查看: 1221| 评论: 1|来自: 蚂蚁部落

JavaScript是一门面向对象的语言,继承方式与C#和Java等迥然不同。

尽管受到许多人的诟病,但不能否则JavaScript中的继承更加强大与灵活。

ES2015对继承方式做了一些表面的修改,实质依然是通过prototype原型实现。

具体参阅JavaScript class 继承一章节,本文仅对ES5常见的继承方式进行一下总结。

首先创建一个父类,后面会逐一演示对其各种不同的继承方式:

[JavaScript] 纯文本查看 复制代码
function Web(webName){
  this.webName=webName;
  this.show=function(){
    console.log("网站名称"+this.webName);
  }
}
Web.prototype.infor=function(url){
  console.log("网站地址是"+url);
}

上面创建一个简单的父类,下面介绍一下子类对其继承的各种方式。

一.原型继承:

关于prototype原型参阅JavaScript prototype 原型一章节。

[JavaScript] 纯文本查看 复制代码运行代码
function Web(webName){
  this.webName=webName;
  this.show=function(){
    console.log("网站名称"+this.webName);
  }
}

Web.prototype.infor=function(url){
  console.log("网站地址是"+url);
}

function Antzone(){}
Antzone.prototype=new Web("蚂蚁部落");
let ant=new Antzone();

console.log(ant.webName);
console.log(ant.show());
console.log(ant.infor());
console.log(ant instanceof Web);
console.log(ant instanceof Antzone);
console.log(ant.constructor === Antzone);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/20/222527ksisjkrygkkkyizx.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).通过prototype原型实现了对父类的继承,只要将父类实例对象设置为子类的原型对象即可。

(2).原型继承可以实现原型上的属性和方法的共享,提高性能。

(3).创建的对象实例是子类的实例也是父类的实例。

最后一个行打印结果为false,ant实例的构造函数分明是Antzone。

constructor属性继承自原型对象,原本是指向构造函数的,然后我们用父类实例重置了子类的原型对象。

具体参阅JavaScript constructor一章节,代码修改如下:

[JavaScript] 纯文本查看 复制代码
function Antzone(){}
Antzone.prototype=new Web("蚂蚁部落");
Antzone.prototype.constructor=Antzone;
let ant=new Antzone();

只要重置一下constructor的指向即可。

二.构造继承:

[JavaScript] 纯文本查看 复制代码运行代码
function Web(webName){
  this.webName=webName;
  this.show=function(){
    return "网站名称"+this.webName;
  }
}

Web.prototype.infor=function(){
  return "网站信息";
}

function Antzone(webName){
  Web.call(this,webName);
}
let ant=new Antzone("蚂蚁部落");

console.log(ant.webName);
console.log(ant.show());
console.log(ant instanceof Web);
console.log(ant instanceof Antzone);
console.log(ant.infor());

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/20/222633da980swxom0a4oxs.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).将父类至于子类之类,然后利用call修改父类的调用对象为子类实例对象。

(2).于是子类可以继承父类的自有属性和方法,但是无法继承原型链上的实例与方法,所以最后一行报错。

(3).实例是子类的实例,并非父类的实例(从instanceof返回值来论,后面代码也是如此)

(4).每一创建子类实例,都是拷贝一份父类自有属性与方法,有点浪费资源。

三.实例继承:

[JavaScript] 纯文本查看 复制代码运行代码
function Web(webName){
  this.webName=webName;
  this.show=function(){
    return "网站名称"+this.webName;
  }
}

Web.prototype.infor=function(){
  return "网站信息";
}

function Antzone(webName){
  let instance = new Web(webName);
  instance.address="青岛市南区";
  return instance;
}
let ant=new Antzone("蚂蚁部落");

console.log(ant.webName);
console.log(ant.show());
console.log(ant instanceof Web);
console.log(ant instanceof Antzone);
console.log(ant.infor());

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/20/222703q7fdvzd7e7nhmw2v.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).在子类内创建父类实例,这样子类就可以继承父类自有和原型链上的方法与属性。

(2).是父类的实例,不是子类的实例。

(3).每一次创建对象实例也是对父类自有属性和方法的一次拷贝,有点浪费性能。

四.寄生组合继承:

[JavaScript] 纯文本查看 复制代码运行代码
function Web(webName){
  this.webName=webName;
  this.show=function(){
    return "网站名称"+this.webName;
  }
}

Web.prototype.infor=function(){
  return "网站信息";
}

function Antzone(webName){
  Web.call(this,webName);
}

(function(){
  let Super = function(){};
  Super.prototype = Web.prototype;
  Antzone.prototype = new Super();
})();

Antzone.prototype.constructor=Antzone;
let ant=new Antzone("蚂蚁部落");

console.log(ant.webName);
console.log(ant.show());
console.log(ant instanceof Web);
console.log(ant instanceof Antzone);
console.log(ant.infor());
console.log(ant.constructor === Antzone);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201812/20/222731c6m6f8gtmpotzm6t.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).在子类中通过call调用父类构造函数,这样就可以继承父类的自有属性与方法。

(2).通过自执行函数,将父类原型对象赋值给空构造函数的Super的原型对象,然后再将子类的原型对象重置为Super对象实例,子类实例也会继承父类原型对象上的属性和方法。

(3).由于是重置的子类原型对象,所以还需要重置一下constructor属性值。

(4).这样可以共享父类的原型对象,性能还不错。


鲜花

握手

雷人

路过

鸡蛋
发表评论

最新评论

引用 双面怪杰 2019-2-16 10:26
看了这么多,继承的原理大概懂了,但是具体项目中是用在哪里呢?

查看全部评论(1)

返回顶部