JS基本功系列-原型链中的一种模块化开发定式: 圣杯模式

admin 2022年5月14日19:22:17安全开发评论3 views3776字阅读12分35秒阅读模式

一、原型继承

1、原型链继承:全量继承,无法实现部分继承

缺点:继承了过多不必要的属性

// 父级
Professor.prototype = {
name: 'Zhang',
tSkill: 'JAVA'
}
function Professor() {}
var professor = new Professor();

// -------------分割线----------

// 子级
Teacher.prototype = professor;
function Teacher() {
this.name = 'Wang',
this.mSkill = 'JS'
}
var teacher = new Teacher();

// -------------分割线----------

// 孙子级
Student.prototype = teacher;
function Student() {
this.name = 'Li',
this.pSkill = 'HTML'
}
var student = new Student();
console.log(student);

2、借助 call/apply 实现继承: 只能借用属性和方法,无法继承原型

缺点:无法继承借用构造函数的原型

Teacher.prototype.wife = 'Liu';

function Teacher(name, mSkill) {
this.name = name;
this.mSkill = mSkill;
}

function Student(name, mSkill, age, major) {
Teacher.apply(this, [name, mSkill]);
this.age = age;
this.major = major;
}

var student = new Student('Zhang', 'JS', 18, 'Computer');
console.log(student);

3、公共原型继承

缺点:两个原型会相互影响,更改其中一个原型,更一个对应的原型也会被更改。

function Teacher() {
this.name = 'Li';
this.tSkill = 'Java';
}
Teacher.prototype = {
pSkill: 'JS'
}
var t = new Teacher();
console.log(t);

function Student() {
this.name = 'Wang';
}
Student.prototype = Teacher.prototype;
Student.prototype.age = 18;//Student里面添加属性,Teacher里面的属性也会跟着改变,这样是不行的;

var s = new Student();
console.log(s);

4、企业级继承:圣杯模式

终极解决方案: 加中间缓冲对象,即可解决只继承父级的原型,而不继承构造属性

//父构造函数
function Teacher() {
this.name = 'Li';
this.tSkill = 'Java';
}
Teacher.prototype = {
pSkill: 'JS'
}
var t = new Teacher();
console.log(t);

// 中间对象缓冲
function Buffer() {}
Buffer.prototype = Teacher.prototype;
var buffer = new Buffer();
console.log(buffer);

// 子构造函数
function Student() {
this.name = 'Wang';
}
Student.prototype = buffer;
Student.prototype.age = 18;
//这里的Teacher.prototype并没有直接赋值给Student.prototype,而是赋值给Buffer.prototype
//Buffer的实例化对象赋值给了Student.prototype
//而通过实例化对象是不能修改自己祖先的prototype的属性和方法的!具体例子详见:
//https://mp.weixin.qq.com/s/n25bWS481nHl6sXzwiE93g
//故Student.prototype的修改是不影响Teacher的prototype的

var s = new Student();
console.log(s);
JS基本功系列-原型链中的一种模块化开发定式: 圣杯模式
原型链图

5、圣杯封装

function inherit(Target, Origin) {
function Buffer(){}
Buffer.prototype = Origin.prototype;
Target.prototype = new Buffer();
// 还原构造器
Target.prototype.constructor = Target;
// 设置继承源
Target.prototype.super_class = Origin;
}

// 使用
function Teacher() {}
Teacher.prototype.name = "Zhang";
function Student() {}
inherit(Student, Teacher);
var t = new Teacher();
var s = new Student();
console.log(s);
console.log(t);

6、企业级的模块化封装:闭包+圣杯封装

//非立即函数执行版本
function test() {
var Buffer = function () {
}

function inherit(Target, Origin) {
Buffer.prototype = Origin.prototype;
Target.prototype = new Buffer();
Target.prototype.constructor = Target;
Target.prototype.super_class = Origin;
}

return inherit
}

var inherit = test()
//立即函数执行版本--->企业级写法--->模块化开发----->防止全局环境污染--->有利于维护
var inherit = (function() {
var Buffer = function() {}
//这里用到的是闭包
return function(Target, Origin) {
Buffer.prototype = Origin.prototype;
Target.prototype = new Buffer();
// 还原构造器
Target.prototype.constructor = Target;
// 设置继承源
Target.prototype.super_class = Origin;
}
})();

function Teacher() {}
Teacher.prototype.name = "Zhang";
function Student() {}
inherit(Student, Teacher);
var t = new Teacher();
var s = new Student();
console.log(s);
console.log(t);

7、企业级协同开发:一个简单的示例

var inherit = (function() {
var Buffer = function() {}
return function(Target, Origin) {
Buffer.prototype = Origin.prototype;
Target.prototype = new Buffer();
// 还原构造器
Target.prototype.constructor = Target;
// 设置继承源
Target.prototype.super_class = Origin;
}
})();


//如果没有"var initPrammer =",那么这个函数就会立即执行
//有了"var initPrammer =",等式右边就会等待着去执行
var initPrammer = (function(){
var Programmer = function(){}
Programmer.prototype = {
name: '程序员',
tool: '计算机',
work: '编写应用程序',
say: function(){
console.log(this.myName + this.name + ',' + this.tool + this.work + ',' + this.lang.toString());
}
}

function FrontEnd(){}
function BackEnd(){}

inherit(FrontEnd, Programmer);
inherit(BackEnd, Programmer);

FrontEnd.prototype.lang = ['HTML', 'CSS'];
FrontEnd.prototype.myName = '前端';
BackEnd.prototype.lang = ['JAVA', 'PHP'];
BackEnd.prototype.myName = '后端';

return {
FrontEnd: FrontEnd,
BackEnd: BackEnd
}
})();

var frontEnd = new initPrammer.FrontEnd();
frontEnd.say();
var backEnd = new initPrammer.BackEnd();
backEnd.say();


原文始发于微信公众号(迪哥讲事):JS基本功系列-原型链中的一种模块化开发定式: 圣杯模式

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月14日19:22:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  JS基本功系列-原型链中的一种模块化开发定式: 圣杯模式 http://cn-sec.com/archives/1007727.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: