JavaScript 继承模式发展史(圣杯模式!!!)

JavaScript继承发展史

01 原型链(传统模式)

若不太了解 原型链 请参考 原型和原型链的定义和使用.

代码解读

//实例
Father.prototype.lastName = 'wang';
	function Father() {
    
    
		this.name = "dad";
	}
	var father = new Father();
	Son.prototype = father;
	function Son() {
    
    }
    var son = new Son();

原型链继承模式

优点:父类的方法和属性得到了复用,并且修改属性是不会影响到父类们的。
缺点:过多的继承了没用的属性。

02 借用构造函数

借用构造函数的思想是在子类构造函数的内部调用父类构造函数,借助apply()和call()方法来改变对象的执行上下文。

代码解读

//实例
function Person(name, age) {
    
    
	this.name = name;
	this.age = age;
}
function Student(name, age, grade) {
    
    
	Person.call(this, name, age);
	this.grade = grade;
}
var stu = new Student();

优点:解决原型中包含引用类型值所带来的问题,还可以传递参数。并且子类的每个实例都有自己的属性,不会相互影响。
缺点:不能继承借用构造函数的原型,每次构造函数都要多走一个函数。

03 共享原型

采用Son.prototype = Father.prototype;的方式,让son和father的原型都指向同一个空间,即不管改变两者之中的哪一个,另一个也会跟着改变。

代码解读

Father.prototype.lastName = 'wang'
function Father() {
    
    }
function Son() {
    
    }
Son.prototype = Father.prototype;
// son和father的原型都指向同一个空间,即不管改变两者之中的哪一个,另一个也会跟着改变
//实例如下:
var son = new Son();
var father = new Father();

优点:用法简单。
缺点:不能随便改动自己的原型。

04 圣杯模式(important!)

在共享原型的基础上进行改进,封装一个inherit 函数,并在其中定义一个函数F用来充当中间层的函数之后让F和父类的原型指向同一地址,再让子类的原型指向这个F的对象来实现了继承。(由于有中间层F的存在,因此父类的原型自始至终都没有受到影响)

代码解读

圣杯模式写法1function inherit(target, origin) {
    
    
	function F() {
    
    };
	F.prototype = origin.prototype;
	target.prototype = new F();
	target.prototype.constructor = target;
	// 让子类的constructor重新指向自己,若不修改则会发现constructor指向的是父类的构造函数
	target.prototype.uber = origin.prototype;
	// “uber”即超类,超级父级(这个属性可以查询究竟继承的谁)
	// “uber”是某些人在模拟class时用来表示super的(因为super是关键字所以不能直接用)。
}

//实例如下:
Father.prototype.lastName = 'wang'
function Father() {
    
    }
function Son() {
    
    }
inherit(Son, Father);
var son = new Son();
var father = new Father();
圣杯模式写法2var inherit = (function () {
    
    
	// 采用闭包方式实现封装和属性私有化
	var F = function () {
    
     };
	return function (Target, Origin) {
    
    
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constructor = Target;
		// 让子类的constructor重新指向自己,若不修改则会发现constructor指向的是父类的构造函数
		Target.prototype.uber = Origin.prototype;
		// “uber”即超类,超级父级(这个属性可以查询究竟继承的谁)
    	// “uber”是某些人在模拟class时用来表示super的(因为super是关键字所以不能直接用)。
	}
}());

//实例如下:
Father.prototype.lastName = 'wang'
function Father() {
    
    }
function Son() {
    
    }
inherit(Son, Father);
var son = new Son();
var father = new Father();

圣杯模式

优点:中间生成了一个对象,起到了隔离的作用。既可以有父辈的属性和方法,改变自己的时候,也不会影响父辈的属性。

个人笔记,欢迎大家交流探讨!

猜你喜欢

转载自blog.csdn.net/Yuki_yuhan/article/details/108248086
今日推荐