目 录CONTENT

文章目录

JS实现继承的六种方式

俊阳IT知识库
2023-01-04 / 0 评论 / 0 点赞 / 360 阅读 / 1,156 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2023-01-04,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
广告

文章已同步至掘金:https://juejin.cn/post/6844903896440111117
欢迎访问😃,有任何问题都可留言评论哦~

你可以不劳而获

继承: 让子对象拥有父对象所有的属性和方法

发扬光大: 子对象在父对象的基础上,有自己的属性和方法

JS特点:生来继承

例如:

let s = { };
s.toString(); //为什么有toString?从__proto__获取的
let a = [1,2]
a.length,a.sort		//从__proto__获取的

JS中的六种继承方式

先说一下原型,如下:

// B是A的原型,A是B的构造函数
A.prototype = B
B.constructor = A

原型链继承

  • 基本思想

利用原型链来实现继承,父类的一个实例作为子类的原型

  • 具体实现
function Parent(yourname){
    this.name = yourname;
}
Parent.prototype.say = function(){
    console.log(this.name)
}

function Son(yourname){
    this.name = yourname;
}
// 让Son去继承Parent上的say方法  继承 
Son.prototype = Parent.prototype
// 修改constructor的指向
Son.prototype.constructor = Son;

let p = new Parent("Hello")
p.say();

let s = new Son("world")
s.say()
  • 优缺点

1.优点:

  • 简单明了
  • 实例是子类的实例,实际上也是父类的一个实例
  • 父类新增原型方法/原型属性,子类都能访问到

2.缺点:

  • 所有子类的实例的原型都共享同一个超类实例的属性和方法
  • 无法实现多继承

构造继承

  • 基本思想

通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例

  • 具体实现
function Parent(yourname) {
	this.name = yourname;
}
Parent.prototype.say = function () {
	console.log(this.name)
}
// 让Son去继承name属性和say方法
function Son(yourname) {
	// 继承属性
	Parent.call(this,yourname)
}
// 继承方法
Son.prototype = Parent.prototype;
Son.prototype.constructor = Son;
  • 优缺点

1.优点:

  • 简单明了,直接继承父类构造函数的属性和方法

2.缺点:

  • 无法继承原型链上的属性和方法

组合继承

  • 基本思想

利用构造继承和原型链组合

  • 具体实现
function Parent(yourname) {
	this.name = yourname;
}
Parent.prototype.say = function () {
	console.log(this.name)
}
// 让Son去继承name属性和say方法
function Son(yourname) {
	// 继承属性
	Parent.call(this, yourname)
}
// 下面的继承使用Son和Parent都指向了同一个原型对象
// Son.prototype = Parent.prototype;
// Son.prototype.constructor = Son;

// 还可以把原型对象copy一份 让Son继承copy过来的
// Parent.prototype  循环一个对象 使用 for in
for(let i in Parent.prototype){
	Son.prototype[i] = Parent.prototype[i]
}
Son.prototype.constructor = Son;
  • 优缺点

1.优点:

  • 解决了构造继承和原型链继承的两个问题

2.缺点:

  • 实际上子类上会拥有父类的两份属性,只是子类的属性覆盖了父类的属性

原型式继承

  • 基本思想

采用原型式继承并不需要定义一个类,传入参数obj,生成一个继承obj对象的对象

  • 具体实现
function object(o){
 function F(){}
 F.prototype = o;
 return new F();
} 


var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"]
};

var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends); //"Shelby,Court,Van,Rob,Barbie" 
  • 优缺点

1.优点:

  • 直接通过对象生成一个继承该对象的对象

2.缺点:

  • 不是类式继承,而是原型式基础,缺少了类的概念

寄生式继承

  • 基本思想

创建一个仅仅用于封装继承过程的函数,然后在内部以某种方式增强对象,最后返回对象

  • 具体实现
function objectCreate(obj){
  function F(){}
  F.prototype = obj
  return new F()
}
function createAnother(original) {
	var clone = object(original);
	clone.sayHi = function() {
		alert("hi");
	};
	return clone;
}
  • 优缺点

1.优点:

  • 原型式继承的一种拓展

2.缺点:

  • 依旧没有类的概念

寄生组合式继承

  • 基本思想

结合寄生式继承和组合式继承,完美实现不带两份超类属性的继承方式

  • 具体实现
function object(o) {
	function F(){}
	F.prototype = o;
	return new F();
}

function inheritPrototype(superType, subType) {
	var prototype = object(superType.prototype);
	prototype.constructor = subType;
	subType.prototype = prototype;
}

function SuperType(name) {
	this.name = name;
	this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {
	alert(this.name);
};

function SubType(name, age) {
	SuperType.call(this, name);
	this.age = age;
}

inheritPrototype(SuperType, SubType);	// 这一句,替代了组合继承中的SubType.prototype = new SuperType()

SubType.prototype.sayAge = function() {
	alert(this.age);
};
  • 优缺点

1.优点:

  • 完美实现继承,解决了组合式继承带两份属性的问题

2.缺点:

  • 过于繁琐,故不如组合继承

^_<

0

评论区