本篇文章给大家带来的内容是关于(超经典)javascript中对象继承方式的总结 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
一、原型链继承
重点:利用原型让一个引用类型继承另外一个引用类型的属性和方法。构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } // 继承自SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.subproperty; }; var example = new SubType(); alert(example.getSuperValue());//true
使用原型创建对象会存在多个实例对引用类型的操作会被篡改的问题,在上面同样存在这个问题,如下:
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){}//即使没有写,也不会影响结果 SubType.prototype = new SuperType(); var example1 = new SubType(); example1.colors.push("black"); alert(example1.colors); //"red,blue,green,black" var example2 = new SubType(); alert(example.colors); //"red,blue,green,black"
两个实例对象example1和example2的colors属性指向相同,改变一个会影响另一个实例的属性。
缺点:
①原型链继承多个实例的引用类型属性指向相同,一个实例修改了原型属性,另一个实例的原型属性也会被修改;
②不能传递参数;
③继承单一。
二、借用构造函数继承
重点:使用.call()和.apply()将父类构造函数引入子类函数,使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类。
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } function SubType(name, age){ // 继承自SuperType SuperType.call(this, name); this.age = age; } var example1 = new SubType("Mike", 23); example1.colors.push("black"); alert(example1.colors);//"red,blue,green,black" var example2 = new SubType(); alert(example2.colors);//"red,blue,green" alert(example1.name); // "Mike" alert(example1.age); // 23
借用构造函数继承的重点就在于SuperType.call(this, name),调用了SuperType构造函数,这样,SubType的每个实例都会将SuperType中的属性复制一份。
缺点:
①只能继承父类的实例属性和方法,不能继承原型属性/方法;
②无法实现构造函数的复用,每个子类都有父类实例函数的副本,影响性能,代码会臃肿。
三、组合继承
重点:将原型链继承和构造函数继承这两种模式的优点组合在一起,通过调用父类构造,继承父类的属性并保留传参,然后通过将父类实例作为子类原型,实现函数复用。
其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承,这样,既通过在原型上定义方法实现了函数复用,又能保证每个实例都有它自己的属性。
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; } // 继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }; var example1 = new SubType("Mike", 23); example1.colors.push("black"); alert(example1.colors); //"red,blue,green,black" example1.sayName(); //"Mike"; example1.sayAge(); //23 var example2 = new SubType("Jack", 22); alert(example2.colors); //"red,blue,green" example2.sayName(); //"Jack"; example2.sayAge(); //22
缺陷:
父类中的实例属性和方法既存在于子类的实例中,又存在于子类的原型中,不过仅是内存占用,因此,在使用子类创建实例对象时,其原型中会存在两份相同的属性/方法。-------这个方法是javascript中最常用的继承模式。
四、 原型式继承
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理,直接将某个对象直接赋值给构造函数的原型。
function object(obj){ function O(){} O.prototype = obj; return new O(); }
object()对传入其中的对象执行了一次浅复制,将O的原型直接指向传入的对象。
var person = { name: "Mike", friends: ["Jack", "Tom", "Joes"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Peter"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("BoBo"); alert(person.friends); //"Jack,Tom,Joes,Peter,BoBo"
ECMAScript5通过新增Object.create()方法规范化了原型式继承,这个方法接收两个参数:一个用作新对象原型的对象和一个作为新对象定义额外属性的对象。
var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
缺点:
①原型链继承多个实例的引用类型属性指向相同(所有实例都会继承原型上的属性),存在篡改的可能;
②无法传递参数,无法实现复用。(新实例属性都是后面添加的)。
五、寄生式继承
重点:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回构造函数。(就像给原型式继承外面套了个壳子,然后return出来)
function createAnother(original){ varclone=object(original); // 过调用函数创建一个新对象 clone.sayHi = function(){ // 以某种方式增强这个对象 alert("hi"); }; return clone; // 返回对象 }
函数的主要作用是为构造函数新增属性和方法,以增强函数。
var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"
缺点:
①原型链继承多个实例的引用类型属性指向相同,存在篡改的可能;
②无法传递参数,没用到原型,无法复用。
六、寄生组合式继承
重点:通过借用构造函数传递参数和寄生模式实现继承属性,通过原型链的混成形式来继承方法,在函数中用apply或者call引入另一个构造函数,可传参。
function inheritPrototype(subType, superType){ var prototype = Object.create(superType.prototype); //Object.create创建对象 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(SubType, SuperType); // 新增子类原型属性 SubType.prototype.sayAge = function(){ alert(this.age); } var example1 = new SubType("abc", 21); var example2 = new SubType("def", 22); example1.colors.push("pink"); // ["red", "blue", "green", "pink"] example1.colors.push("black"); // ["red", "blue", "green", "black"]
寄生组合继承集合了前面几种继承优点,几乎避免了上面继承方式的所有缺陷,是执行效率最高也是应用面最广的。
缺点:
实现的过程相对繁琐。
为什么要学习这些继承方式,明明可以直接继承为什么还要搞这么麻烦?主要是为了学习它们的思想,打下更好的基础,为以后阅读框架源码,或自己封装组件甚至框架大有益处。
时间有点匆忙,没有加上ES6的extends。
相关推荐:
以上是(超经典)javascript中对象继承方式的总结的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver CS6
视觉化网页开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版