JavaScript设计模式学习笔记(一)

JavaScript设计模式学习笔记(一)

      • 一、学习设计模式的目的
      • 二、模式分类
        • 创建型模式
        • 结构型模式
        • 行为型模式
      • 三、关于this的一个小题目

本系列博客主要是面向自己创作,实属自己的读书笔记,注重记录一些重点,并摘录引用一些大佬对于部分知识点的解释,帮助自己翻阅和理解,一定要配合原著食用。

一、学习设计模式的目的

JavaScript是多模式混合的,面向对象,以原型为基础,并拥有动态数据类型。一方面将函数看做一等公民,允许函数式编程的风格,另一方面,也不排斥传统的面向对象方式进行开发,甚至在之后的ES6+ 的标准中引入了面向对象相关的一些原生支持。
这使得 JavaScript成为功能十分强大的语言,赋予开发者很大的开发灵活性,但同时也导致编程风格、习惯以及技术的碎片化,进而导致同一个功能实现的多样化。这种情况下,对于这些传统的、强面向对象的设计模式会有各种类型的实现,有时候你甚至会觉得其中的某些有点牵强。
但是这些并不妨碍使用 JavaScript 来表达设计模式的理念、它所要解决的问题,和它的核心思想,这才是我们所要关注的核心。
因此并不是所有设计模式都是适合 JavaScript的,我们需要注意一些比较常见的设计模式,比如工厂模式、单例模式、发布-订阅模式,而对于一些不那么常用的模式,则可以浅尝辄止,吸收其主要思想即可。

综上所述,了解设计模式不仅对未来工作提供帮助,还能帮助我去了解领域驱动设计,秉持着这两点目的,我打算自此开始用一个月的时间了解一下设计模式,大致的知识体系如下:
JavaScript设计模式学习笔记(一)_第1张图片

二、模式分类

创建型模式

单例模式: 保证一个类只有一个实例,并提供一个访问它的全局访问点;
工厂模式: 根据输入的不同返回不同类的实例,一般用来创建同一类对象;
抽象工厂模式: 通过对类的工厂抽象,使其业务用于对产品类簇的创建;
建造者模式: 分步构建一个复杂对象,使得同样的构建过程可以采用不同的表示;

结构型模式

代理模式: 为目标对象创造一个代理对象,以控制对目标对象的访问;
享元模式: 运用共享技术来有效地支持大量细粒度对象的复用,减少创建的对象的数量;
适配器模式: 解决两个软件实体间接口不兼容的问题;
装饰者模式: 向一个现有的对象添加新的功能,同时又不改变其结构;
外观模式: 为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问;
组合模式: 用小的子对象构建更大的对象,使得对单个对象和组合对象具有一致的访问性;
桥接模式: 将类的抽象部分与实现部分分离,使它们可以独立地变化;

行为型模式

发布-订阅模式: 多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为;
策略模式: 定义了一系列算法,并将每个算法封装起来,使它们可以相互替换;
状态模式: 允许一个对象在其内部状态发生改变时改变其行为能力;
模板方法模式: 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤;
迭代器模式: 提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示;
命令模式: 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开;
职责链模式: 把请求从链中的一个对象传到下一个对象,直到请求被响应为止;
中介者模式: 定义一个中介对象来简化原有对象之间的复杂耦合关系;

实际上,很多设计模式在实习或者日常demo的代码中都有经常使用,比如单例模式、工厂模式、装饰者模式、发布-订阅模式、命令模式,只不过在那个时候我不太清楚他们的“学名”,也没有对他们进行归纳性总结,这次的学习应该注重对设计模式的归纳总结与应用。

三、关于this的一个小题目

this 是在函数被调用时确定的,它的指向完全取决于函数调用的地方,而不是它被声明的地方(除箭头函数外)。当一个函数被调用时,会创建一个执行上下文,它包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息,this 就是这个记录的一个属性,它会在函数执行的过程中被用到。
这部分内容其实已经比较熟悉了,但是在书上看到一个关于this的小题目,好像以前见过类似的,拿出来分享一下:
分析输出为什么不同?

var a = 20

var obj = {
    a: 40,
    foo:() => {
        console.log(this.a)
    
        function func() {
            this.a = 60
            console.log(this.a)
        }
    
        func.prototype.a = 50
        return func
    }
}

var bar = obj.foo()        // 浏览器中输出: 20
bar()                      // 浏览器中输出: 60
new bar()                  // 浏览器中输出: 60
var a = 20

var obj = {
    a: 40,
    foo: function() {
        console.log(this.a)
        
        function func() {
            this.a = 60
            console.log(this.a)
        }
        
        func.prototype.a = 50
        return func
    }
}

var bar = obj.foo()        // 浏览器中输出: 40
bar()                      // 浏览器中输出: 60
new bar()                  // 浏览器中输出: 60

下期解释!

你可能感兴趣的:(前端,javascript,设计模式,学习)