阅读 15

浅谈js中的继承和拷贝(上)

----欢迎查看我的博客----

继承

  继承,这个词可能在静态语言听得比较多。今天主要讲讲js的继承,我们先来看下生活中的继承:

image

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。

java的继承

class 父类 {
}

class 子类 extends 父类 {
}
复制代码

是不是有点眼熟,对没错,我们的es6的继承也是这样的书写格式,这个我们后面再说。

js继承方式

  简单明了,废话不多说,本博客一直简单粗暴,直接上代码

用call或apply方法继承

function Animal(){
	this.find = '动物'
}

function Cat(name,color){
	Animal.apply(this, arguments);
	//Animal.call(this,name,color)
	this.name = name;
	this.color = color;

}


var cat = new Cat('大黄','黄色');
console.info(cat.find); //动物
复制代码

我们看到,此时的cat已经可以调用animal的属性了

实例继承

function Animal(){
	this.find = '动物'
}

function Cat (name,color){
	this.name = name;
	this.color = color;
}

Cat.prototype = new Animal();
Cat.prototype.__proto__.constructor = Cat;
var cat = new Cat("大毛","黄色");
console.log(cat.find); // 动物
复制代码

这里也继承成功,可以看到我们将Cat的prototype对象指向一个Animal的实例。然后又把Cat的Cat.prototype.proto.constructor从animal指向cat,因为指向实例后,Cat.prototype.proto.constructor也等于了Animal,所以我们要指代回来.

借此,我们可以看到function函数的继承。上述代码其实可以这样写。

function Animal(){
	this.find = '动物'
}

function Cat(name,color){
	this.name = name;
	this.color = color;
}

var obj = {};
obj.__proto__ = Animal.prototype;
Animal.call(obj);
Cat.prototype = obj;
Cat.prototype.__proto__.constructor = Cat
复制代码

在这里我们可以看到 我们的 new 其实做了三部东西。第一步

  • 创建了一个空的对象
  • 第二部对象的_proto_ 等于了函数的 prototype
  • 第三部我们把方法的this指向指向了 obj

prototype继承

function Animal(){ }

Animal.prototype.find = "动物";

function Cat (name,color){
	this.name = name;
	this.color = color;
}

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

var cat1 = new Cat("大毛","黄色");

console.log(cat1.find); // 动物
复制代码

这个例子用了prototype的继承,这里我们用了Object.create,只是为什么呢,直接Cat.prototype = Animal.prototype;可以吗。当然不。

b.prototype = Object.create(a.prototype);
Object.create是es5提出的,余生实现是这样的:

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
};
复制代码

此时,b已经集成了a的所有原型,并且给B增加原型,a不会受到影响。

但如果我们直接这么做:

b.prototype = a.prototype;

那么,我们给b添加原型的属性时,会影响到a的相关原型属性,并进行覆盖.

非构造函数继承

var Chinese = {
	nation:'中国'
};
var Doctor ={
	career:'医生'
};
function a (){}
a.prototype = Chinese
var newdoc = new a();
newdoc.career = '医生';
console.log(newdoc.nation); //中国
复制代码

es6的继承

class a extends b {
  constructor() {
    super();
  }
}
复制代码

es6非常简单,只要class,extends,construction,super等简单关键字就能完成继承,回头在看下开头提到的java继承,会发现基本一模一样。

结语

  本章讲了js的几种基本的继承方式,下一节我们来讲如何拷贝,相信很多兄弟小姐姐们都懂的,记录一波。完事,抽根睡前烟,搬完家没睡好,认床。。累的不行了,碎觉,晚安

评论