JavaScript 进阶实战课
石川
JavaScript Patterns and Anti-Patterns 等开源项目创建者,O'Reilly 技术评审
15066 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
JavaScript 进阶实战课
15
15
1.0x
00:00/00:00
登录|注册

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
立即购买
登录 后留言

全部留言(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
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部