一入前端深似海,从此红尘是路人系列第一弹之浅析JavaScript继承

简介: 继承算是JavaScript中的一大难点也是必须掌握的知识点。接下来我会列举一些我们常见的继承并给出对应一些的code方便大家理解。

继承算是JavaScript中的一大难点也是必须掌握的知识点。接下来我会列举一些我们常见的继承并给出对应一些的code方便大家理解。

1.类式继承,既子类原型继承父类实例化。但是当我利用new关键字实例化子类的时候,当我改变子类继承到父类属性的时候,会污染到再次实例化的子类它所继承到的属性。具体如下


function SuperClass(){
	this.superValue = true;
	this.languages= ['JS','JAVA'];
}
SuperClass.prototype.getSuperValue = function(){
	return this.superValue;
}
function SubClass(){
	this.subValue = false;
}
SubClass.prototype = new SuperClass();
SubClass.prototype.getSubValue = function(){
	return this.subValue;
}
var sub = new SubClass();
console.log(sub.getSuperValue());
console.log(sub.getSubValue());
console.log(sub instanceof SuperClass); //true
console.log(sub instanceof SubClass);	//true
console.log(SubClass instanceof SuperClass); //false
console.log(SubClass.prototype instanceof SuperClass); //true
console.log(sub.languages) //['JS','JAVA']
sub.languages.push('HTML');
var sub1 = new SubClass();
console.log(sub1.languages); //['JS','JAVA','HTML']
2.构造函数继承,即在子类构造函数中利用call()更改作用域,将子类变量在父类中执行一遍,从而完成继承。该继承方式只能继承父类构造函数中的属性和方法,并不能直接继承到父类原型。


function SuperClass(id,books){
	this.id = id;
	this.books = ['JS','JAVA'];
}
SuperClass.prototype.showBooks = function(){
	return this.books;
}
function SubClass(id,books){
	SuperClass.call(this,id,books)
}
var sub = new SubClass();
sub.books.push('CSS');
console.log(sub.books); //['JS','JAVA','CSS']
var sub1 = new SubClass('superClass');
console.log(sub1.books); //['JS','JAVA']
console.log(sub.showBooks()); //Uncaught TypeError: sub.showBooks is not a function

3.组合继承,即将类式继承和构造函数继承进行功能的结合,形成一个更为优良的继承方式。该继承结合了类式继承和构造函数继承,即继承了父类原型,又继承了父类构造函数中的属性和方法。这样的好处就是在用new关键字实例化一个子类的时候改变该子类继承到的属性,不会影响下一个实例化的子类继承到的属性。但是该继承方式的缺点就是子类原型继承父类实例化的时候,也会跑一次父类的构造函数。

function SuperClass(name){
	this.name = name;
	this.books = ['JS','JAVA'];
}
SuperClass.prototype.getName = function(){
	return this.name;
}
function SubClass(name,time){
	SuperClass.call(this,name);
	this.time = time;
}
SubClass.prototype = new SuperClass('superClass');
SubClass.prototype.getTime = function(){
	return this.time;
}
var sub = new SubClass('superClass');
sub.books.push('CSS');
console.log(sub.books); //['JS','JAVA','CSS']
console.log(sub.getName()); //superClass
var sub1 = new SubClass('superClass');
console.log(sub1.books); //['JS','JAVA']
4.原型式继承,它是对类式继承的一个封装,在原型式继承中会声明一个过渡对象,为的就是创建要返回的新的实例化对象。这里由于F过渡类的构造函数没有内容,所以开销比较小,使用起来也比较方便。但还是有着类式继承一样的问题。

function inheritObject(o){
	//声明一个过渡函数
	function F(){}
	//过渡对象的原型继承父对象
	F.prototype = o;
	return new F();
}
var book = {
	name:'js book',
	alikeBook:['css book','html book']
}
var newBook = inheritObject(book);
newBook.name = 'ajax book';
newBook.alikeBook.push('xml book');
var otherBook = inheritObject(book);
otherBook.name = 'flash book';
otherBook.alikeBook.push('as book');
console.log(newBook.name); //ajax book
console.log(newBook.alikeBook); //['css book','html book','xml book','as book']
console.log(otherBook.name); //flash book
console.log(otherBook.alikeBook); //['css book','html book','xml book','as book']
console.log(book.name); //js book
console.log(book.alikeBook); //['css book','html book','xml book','as book']
5.寄生式继承,它是对原型继承的第二次封装,让新创建的对象不仅仅有父类中的属性和方法而且还可以添加新的属性和方法。

//声明基对象
function inheritObject(o){
	//声明一个过渡函数
	function F(){}
	//过渡对象的原型继承父对象
	F.prototype = o;
	return new F();
}
var book = {
	name:'js book',
	alikeBook:['css book','html book']
}
function createBook(obj){
	//通过原型继承方式创建对象
	var o = new inheritObject(obj);
	//拓展新对象
	o.getName = function(){
		console.log(this.name);
	};
	//返回拓展后的新对象
	return o;
}

6.寄生组合式继承,它将寄生式继承和构造函数继承进行结合,形成一个完美的继承方式。


/**
 * 寄生式继承 继承原型
 * 传递参数 subClass 子类
 * 传递参数 superClass 父类
 */
function inheritObject(o){
	//声明一个过渡函数
	function F(){}
	//过渡对象的原型继承父对象
	F.prototype = o;
	return new F();
}
function inheritPrototype(subClass,superClass){
	//复制一份父类的原型副本保存在变量
	var p = inheritObject(superClass.prototype);
	//修正因为重写子类原型导致子类的constructor指向父类
	p.constructor = subClass;
	//设置子类的原型
	subClass.prototype = p;
}
//定义父类
function SuperClass(name){
	this.name = name;
	this.colors = ['red','blue'];
}
//定义父类原型方法
SuperClass.prototype.getName = function(){
	return this.name;
}
//定义子类
function SubClass(name,time){
	//构造函数继承
	SuperClass.call(this,name);
	//子类新增属性
	this.time = time;
}
//寄生式继承父类原型
inheritPrototype(SubClass,SuperClass);
//子类新增原型方法
SubClass.prototype.getTime =function(){
	return this.time;
}
var test1 = new SubClass('js book',2014);
var test2 = new SubClass('csc book',2013);
test1.colors.push('black');
console.log(test1.colors); //['red','blue','black']
console.log(test2.colors); //['red','blue']
console.log(test2.getName());
console.log(test2.getTime());

至此,最终完美的寄生组合式继承便由此诞生了。

此篇文章只是我个人的一些见解,希望可以帮助到一些对于继承还比较模糊的小伙伴们。当然,如果有小伙伴觉着哪里有问题,欢迎指出,大家一起探讨交流。

原文发布时间为:2016年09月10日
原文作者: qiangdada 

本文来源:开源中国 如需转载请联系原作者









目录
相关文章
|
2天前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
11天前
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
|
6天前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
20 4
|
4天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
4天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
5天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
5天前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
17 1
|
9天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
15 1
|
20天前
|
前端开发 JavaScript 安全
JavaScript前端开发技术
JavaScript(简称JS)是一种广泛使用的脚本语言,特别在前端开发领域,它几乎成为了网页开发的标配。从简单的表单验证到复杂的单页应用(SPA),JavaScript都扮演着不可或缺的角色。
17 3
|
1天前
|
前端开发 JavaScript 安全
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第7天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤。包括项目准备、安装 `javascript-obfuscator`、配置 Vite 构建以应用混淆,以及最终构建项目进行混淆。通过这些步骤,可以有效提升前端代码的安全性,防止被他人轻易分析和盗用。
下一篇
无影云桌面