08|深入理解继承、Delegation和组合
石川
你好,我是石川。
关于面向对象编程,最著名的一本书就数GoF(Gang of Four)写的《设计模式:可复用面向对象软件的基础》了。这本书里一共提供了 23 种不同的设计模式,不过今天我们不会去展开了解这些细节,而是会把重点放在其中一个面向对象的核心思想上,也就是组合优于继承。
在 JS 圈,有不少继承和组合的争论。其实无论是继承还是组合,我们都不能忘了要批判性地思考。批判性思考的核心不是批判,而是通过深度思考核心问题,让我们对事物能有自己的判断。
所以,无论是继承还是组合,都只是方式、方法,它们要解决的核心问题就是如何让代码更加容易复用。
那么接下来,我们就根据这个思路,看看 JavaScript 中是通过哪些方法来解决代码复用这个问题的,以及在使用不同的方法时它们各自解决了什么问题、又引起了什么问题。这样我们在实际的业务场景中,就知道如何判断和选择最适合的解决方式了。
继承
在传统的 OOP 里面,我们通常会提到继承(Inheritance)和多态(Polymorphism)。继承是用来在父类的基础上创建一个子类,来继承父类的属性和方法。多态则允许我们在子类里面调用父类的构建者,并且覆盖父类里的方法。
那么下面,我们就先来看下在 JavaScript 里,要如何通过构建函数来做继承。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了面向对象编程中的继承、授权和组合的概念。作者首先强调了批判性思考的重要性,指出继承和组合只是解决代码复用问题的不同方式和方法。在继承方面,文章介绍了在JavaScript中如何通过extends和super来实现继承和多态。授权方面,通过Object.create()方法展示了如何通过原型来实现授权,让对象在得到授权后获得新的能力。最后,文章提到了组合,介绍了通过apply和call来实现隐性混入,以及通过class来实现授权的方式。 文章还讨论了通过拷贝赋予重用的方法,包括浅拷贝和深度拷贝的概念,并提供了具体的代码示例。此外,还介绍了如何通过组合混入多个对象的属性,以及在React中如何利用组合优于继承的特点。 总的来说,本文通过具体的代码示例和比喻,深入浅出地解释了继承、授权和组合在JavaScript中的应用,为读者提供了清晰的技术概览。文章还提到了不同技术大师对于授权和组合的不同观点,强调了在面对问题时需要灵活选择适合的解决方案。 在思考题部分,文章鼓励读者尝试实现JS中的类和继承中的super,以及原型和授权中的Object.create(),并欢迎读者分享学习心得或提出问题。 总之,本文内容丰富,涵盖了面向对象编程中的重要概念和技术应用,适合读者快速了解并深入学习。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《JavaScript 进阶实战课》,新⼈⾸单¥59
《JavaScript 进阶实战课》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(5)
- 最新
- 精选
- laoergege组合优于继承,是不是更加适用于平时业务开发?做为基础设施给用户使用的场景,继承更加简洁方便?比如 react 框架下,提供的 Component 类。
作者回复: 这个比喻挺好,很多时候是这样的。
2022-10-16归属地:北京3 - Change/********* JS 中的类和继承中的 super **************** */ function Widget() { this.appName = "核心微件"; } Widget.prototype.getAppName = function () { return this.appName; }; function Calendar() { // 调用super let widget = new Widget(); this.__proto__.__proto__ = widget.__proto__; // Calendar.prototype.__proto__ = Widget.prototype; for (let key in widget) { if (widget.hasOwnProperty(key)) { this[key] = widget[key]; } } this.name = "Calendar"; } Calendar.prototype.getName = function () { return this.name; }; /**********Object.create************** */ function Person() { this.name = "Person"; } // Object.Create function ObjectCreate(o) { let obj = {}; obj.__proto__ = o; return obj; } let o = ObjectCreate(new Person());2022-10-13归属地:河北1
- 褚琛//js中的类和继承 function Widget (appName) { this.appName = appName } Widget.prototype.getName = function() { return this.appName; } function Calendar (appName) { Widget.call(this, appName); } Calendar.prototype = { ...Widget.prototype }; var calendar = new Calendar('日历应用'); console.log(calendar.hasOwnProperty("appName")); // 返回 true console.log(calendar.getName()); // 返回 "日历应用" console.log(typeof calendar.getName); // 返回 function console.log(calendar.getName()); // 返回 “日历应用” //Object.create() function create(o) { let Cls = function() {}; let obj = new Cls(); obj.prototype = o; return obj; }2022-10-10归属地:海南1
- 神佑小鹿ES6 当中的 assign 来做到组合混入,我看下和 java 的组合有很大的区别,java 是通过持有其他对象的引用来实现组合,js 是直接拷贝属性,差异很大2023-03-13归属地:广东
- 神佑小鹿作为一个 Android 工程师,我怎么感觉授权就是继承呢??就是基于原型链的继承??2023-03-13归属地:广东1
收起评论