JavaScript ES2015中对象继承的模式
钥匙要点
- >使用ES2015,JavaScript现在具有专门定义类的语法,以保持代码清洁,最小化层次结构深度并避免重复代码。 >多重继承(由某些经典OOP语言支持的功能)允许创建从多个基类继承的类。但是,它遇到了钻石问题,其中两个父类定义了相同的方法。
- 混合蛋白,仅包含方法的微小类是躲避钻石问题的另一种策略。 Mixins不用扩展这些类,而是在另一个类中包含。 >
- >尽管班级语法给出了一种幻想,即JavaScript是一种基于类的OOP语言,但事实并非如此。大多数方法都需要修改对象的原型以模仿多重继承。使用类工厂功能是使用Mixins组成类的可接受策略。
- JavaScript的 > ES2015(以前称为ES6)的已久的到来,配备了专门定义类的语法。在本文中,我将探讨是否可以利用类语法来撰写较小零件的类。

想象我们正在建立一个玩家生活在动物世界中的游戏。有些是朋友,有些是敌对的(像我这样的狗人可能会说所有猫都是敌对的生物)。我们可以创建一个hostileanimal,它可以扩展动物,以充当猫的基础。在某个时候,我们决定添加旨在伤害人类的机器人。我们要做的第一件事是创建机器人类。现在,我们有两个具有相似属性的类。例如,hostileanimal和机器人都可以攻击()。
>
>如果我们可以以某种方式在单独的类或对象中定义敌意,请说敌对,我们可以将其重用为CAT作为机器人。我们可以以各种方式做到这一点。
>多重继承
是某些经典的OOP语言支持的功能。顾名思义,它使我们能够创建一个从多个基类继承的类。查看CAT类在以下Python代码中如何扩展多个基类:and接口
是(键入)经典OOP语言中的常见功能。它允许我们定义类应包含的方法(有时是属性)。如果该课程没有,编译器将引起错误。如果CAT没有攻击()或walk()方法:<span>class Animal(object): </span> <span>def walk(self): </span> <span># ... </span> <span>class Hostile(object): </span> <span>def attack(self, target): </span> <span># ... </span> <span>class Dog(Animal): </span> <span># ... </span> <span>class Cat(Animal, Hostile): </span> <span># ... </span> dave <span>= Cat(); </span>dave<span>.walk(); </span>dave<span>.attack(target); </span>
a recap:es2015类语法
>如果您没有机会参加ES2015课程或觉得自己对它们的了解不足,请务必阅读Jeff Mott面向对象的JavaScript - 在继续之前深入研究ES6课程。 > 简而言之:<span>interface Hostile { </span> <span>attack(); </span><span>} </span> <span>class Animal { </span> <span>walk(); </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal implements Hostile { </span> <span>attack() { </span> <span>// ... </span> <span>} </span><span>} </span>
>类foo {...}描述了一个名为foo
的类
类foo扩展bar {...}描述了一个foo的类,该类扩展了另一个类,bar>
在类块中,我们可以定义该类的属性。在本文中,我们只需要了解构造函数和方法:- 构建器(){...}是一个保留函数,在创建时执行(new foo())
- > foo(){...}创建一个名为foo 的方法
级语法主要是JavaScript原型模型上的句法糖。它不是创建类,而是创建一个函数构造函数:
>- 的要点是,JavaScript不是基于类的OOP语言。甚至可能认为语法是欺骗性的,给人的印象是。 组成ES2015类
- 可以通过创建一个抛出错误的虚拟方法来模仿 接口。一旦继承,就必须覆盖该功能以避免错误:
如前所述,这种方法依赖于继承。要继承多个类,我们将需要多个继承或混合素。
<span>class Animal { </span> <span>// ... </span><span>} </span> <span>trait Hostile { </span> <span>// ... </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span> <span>class Robot { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span>
>探索应用多种继承和混合素的各种方法的时间。以下所有检查的策略均可在GitHub上获得。
>
object.assign(childclass.protype,mixin ...)> ES2015前,我们使用原型来继承。所有功能都有一个原型属性。使用新的myFunction()创建实例时,将原型复制到实例中的属性。当您尝试访问不在实例的属性时,JavaScript引擎将尝试在原型对象中查找。
进行演示,请查看以下代码:<span>class Foo {} </span><span>console.log(typeof Foo); // "function" </span>
可以在运行时创建和修改这些原型对象。最初,我试图将课程用于动物和敌对:
<span>class Animal(object): </span> <span>def walk(self): </span> <span># ... </span> <span>class Hostile(object): </span> <span>def attack(self, target): </span> <span># ... </span> <span>class Dog(Animal): </span> <span># ... </span> <span>class Cat(Animal, Hostile): </span> <span># ... </span> dave <span>= Cat(); </span>dave<span>.walk(); </span>dave<span>.attack(target); </span>
上面的方法是不起作用的,因为类方法是>不枚举的。实际上,这意味着对象。分配(...)不从类复制方法。这也使得很难创建一个将方法从一个类复制到另一个类的函数。但是,我们可以手动复制每种方法:
><span>interface Hostile { </span> <span>attack(); </span><span>} </span> <span>class Animal { </span> <span>walk(); </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal implements Hostile { </span> <span>attack() { </span> <span>// ... </span> <span>} </span><span>} </span>
>另一种方法是抛弃类并使用对象作为混合物。积极的副作用是Mixin对象不能用于创建实例,以防止滥用。
<span>class Animal { </span> <span>// ... </span><span>} </span> <span>trait Hostile { </span> <span>// ... </span><span>} </span> <span>class Dog extends Animal { </span> <span>// ... </span><span>} </span> <span>class Cat extends Animal { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span> <span>class Robot { </span> <span>use Hostile; </span> <span>// ... </span><span>} </span>
- 混合蛋白不能初始化
- >
需要额外的代码
- 行
- object.assign()有点晦涩 与ES2015类合作的重塑原型继承
- 在构造函数中编写对象 >
>我们可以利用该功能从子类内部的多个类中构成对象。请注意,object.sign(...)仍然与Mixin类无法正常工作,因此我在这里也使用了对象:
<span>class Foo {} </span><span>console.log(typeof Foo); // "function" </span>
>
<span>class IAnimal { </span> <span>walk() { </span> <span>throw new Error('Not implemented'); </span> <span>} </span><span>} </span> <span>class Dog extends IAnimal { </span> <span>// ... </span><span>} </span> <span>const robbie = new Dog(); </span>robbie<span>.walk(); // Throws an error </span>
我认为我们可以同意后者更可读。
<span>function <span>MyFunction</span> () { </span> <span>this.myOwnProperty = 1; </span><span>} </span><span>MyFunction.prototype.myProtoProperty = 2; </span> <span>const myInstance = new MyFunction(); </span> <span>// logs "1" </span><span>console.log(myInstance.myOwnProperty); </span><span>// logs "2" </span><span>console.log(myInstance.myProtoProperty); </span> <span>// logs "true", because "myOwnProperty" is a property of "myInstance" </span><span>console.log(myInstance.hasOwnProperty('myOwnProperty')); </span><span>// logs "false", because "myProtoProperty" isn’t a property of "myInstance", but "myInstance.__proto__" </span><span>console.log(myInstance.hasOwnProperty('myProtoProperty')); </span>
pros
<span>class Animal { </span> <span>walk() { </span> <span>// ... </span> <span>} </span><span>} </span> <span>class Dog { </span> <span>// ... </span><span>} </span> <span>Object.assign(Dog.prototype, Animal.prototype); </span>
>它有效,我猜
>cons
- 非常模糊的 ES2015类语法
滥用ES2015类
- 类工厂功能
- 这种方法利用JavaScript在运行时定义类的能力。
- 首先,我们需要基础类。在我们的例子中,动物和机器人充当基础类别。如果您想从头开始,一个空的班级也可以。 >
>现在,我们可以将任何类传递给敌对功能,该函数将返回一个新的类,结合敌对的新类,以及我们传递给该功能的任何类:
我们可以通过几个类进行管道应用多个混合素:
<span>Object.assign(Cat.prototype, { </span> <span>attack: Hostile.prototype.attack, </span> <span>walk: Animal.prototype.walk, </span><span>}); </span>
pros
<span>const Animal = { </span> <span>walk() { </span> <span>// ... </span> <span>}, </span><span>}; </span> <span>const Hostile = { </span> <span>attack(target) { </span> <span>// ... </span> <span>}, </span><span>}; </span> <span>class Cat { </span> <span>// ... </span><span>} </span> <span>Object.assign(Cat.prototype, Animal, Hostile); </span>
>更容易理解,因为所有信息都在类声明标题中
<span>class Answer { </span> <span>constructor(question) { </span> <span>return { </span> <span>answer: 42, </span> <span>}; </span> <span>} </span><span>} </span> <span>// { answer: 42 } </span><span>new Answer("Life, the universe, and everything"); </span>
cons >当我决定研究此主题并撰写有关它的文章时,我希望JavaScript的原型模型有助于生成课程。由于类语法使方法无法恢复,因此对象操纵变得更加困难,几乎不切实际。 类语法可能会产生幻想,即JavaScript是一种基于类的OOP语言,但事实并非如此。使用大多数方法,您将必须修改对象的原型以模仿多重继承。使用类工厂功能的最后一种方法是使用Mixins组成类的可接受策略。
如果出于任何原因,您仍然喜欢经典的编程,则可能需要研究编译为JavaScript的语言。例如,打字稿是JavaScript的超集,它添加了(可选的)静态键入和您将从其他经典OOP语言中识别的模式。 您是否要在项目中使用上述两种方法?您找到了更好的方法吗?在评论中让我知道! javaScript ES2015对象继承经常询问问题
>在JavaScript中的经典和原型继承之间有什么区别?一个类定义一个对象的蓝图,对象是类的实例。继承是通过从超类创建子类来实现的。另一方面,JavaScript使用原型继承,其中对象直接从其他对象继承。这是更灵活的,因为可以在运行时扩展或动态更改对象。 > javaScript如何处理多个继承? > javaScript ES2015中的'构造函数是什么?在javascript ES2015中如何使用它?用于创建和初始化类中的对象的特殊方法。在继承的上下文中,子类构造函数必须使用“超级”关键字调用超级类构造函数,然后才能使用'this'关键字。 > 如何在JavaScript中添加属性? >
结论
>'超级'关键字在JavaScript ES2015中如何工作?在对象的父上调用功能。当在构造函数中使用时,“超级”关键字单独出现,必须在使用“此”关键字之前使用。 “超级”关键字也可用于在方法中的父对象上调用函数。
> JavaScript中的“原型”是什么?在JavaScript中如何使用它在继承中?此属性是对另一个对象的原型对象的引用。创建函数时,其原型对象也会通过函数的原型属性创建并链接。当使用构造函数函数创建对象时,它从其构造函数的原型中继承了属性和方法。
javaScript不直接支持多个继承。但是,可以使用混合蛋白间接实现它。混合蛋白是一种涉及将属性从一个对象复制到另一个对象的技术。这允许对象从多个来源继承属性和方法。
>>
>我如何在JavaScript ES2015中的子类中覆盖一个方法?您可以通过简单地定义子类中具有相同名称的方法来覆盖子类中的方法。新方法将在子类的实例上调用。 > JavaScript中的“新”关键字用于创建类或构造函数函数的实例。在继承的上下文中,“新”关键字用于创建一个子类的实例,该子类从超级类继承属性和方法。>
以上是JavaScript ES2015中对象继承的模式的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。
