my-blog
my-blog copied to clipboard
公众号【前端技匠】作者
什么是原型链
当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找,如果prototype没有,就会去prototype关联的前辈prototype那里寻找,如果再没有则继续查找Prototype.Prototype引用的对象,依次类推,直到Prototype.….Prototype为undefined(Object的Prototype就是undefined)从而形成了所谓的“原型链”。 其中foo是Function对象的实例。而Function的原型对象同时又是Object的实例。这样就构成了一条原型链。 #### instanceof 确定原型和实例之间的关系 用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上 对象的__proto__指向自己构造函数的prototype。obj.__proto__.__proto__...的原型链由此产生,包括我们的操作符instanceof正是通过探测obj.__proto__.__proto__... === Constructor.prototype来验证obj是否是Constructor的实例。 ```js function C(){} var o = new C(){} //true 因为Object.getPrototypeOf(o) === C.prototype o instanceof C ``` instanceof只能用来判断对象和函数,不能用来判断字符串和数字 #### isPrototypeOf 用于测试一个对象是否存在于另一个对象的原型链上。 判断父级对象...
### 定义 定义一系列的算法, 把它们一个个封装起来, 并且使它们可相互替换。 ### 优缺点 `优点` 1. 算法可以自由切换。 2. 避免使用多重条件判断。 3. 扩展性好,符合开闭原则。 `缺点` 1. 策略类会增多。 2. 所有策略类都需要对外暴露。 ### 实战 在vue中有一个合并选项策略 `optionMergeStrategies`,它的功能就是把选项添加一些策略,可以达到我们对选项数据操作的目的 官方例子,将选项 `_my_option` 添加策略,让它的值加一 ```js Vue.config.optionMergeStrategies._my_option = function...
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 ### 优缺点 `优点` 1. 观察者和被观察者是抽象耦合的。 2. 建立一套触发机制。 `缺点` 1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。 ### 实战 比如公众号,有多个人订阅,每天定时发送公众号文章 1. 建立一个 Persen 类,用于创建人物(观察者/订阅着) 2. 建立 Subject 类,用于建立与观察者之间的关系(被注入到观察者的依赖) 3. 修改状态触发更新 ```js...
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 `优点` 1. 更好的可读性 2. 装饰类和被装饰类可以独立发展,不会相互耦合 3. 装饰模式是继承的一个替代模式 4. 装饰模式可以动态扩展一个实现类的功能。 `缺点` 1. 多层装饰比较复杂。 ### 实战 比如我们要点击一个按钮,但是这个按钮点击时我们想给他加上埋点并做一些登陆的逻辑 我这里使用了 `es7` 的语法糖,当然不用语法糖也可以做,但是我觉得用的话更简洁一些 ```js // Button 类,内部有一个 click 方法 // 对click方法做了两个修饰 //...
### 设计模式的六大原则 1. 开闭原则(Open Close Principle) 开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 2. 里氏代换原则(Liskov Substitution Principle) 里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 3. 依赖倒转原则(Dependence Inversion Principle) 这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。 4. 接口隔离原则(Interface Segregation Principle) 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。 5. 迪米特法则,又称最少知道原则(Demeter Principle) 最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。 6. 合成复用原则(Composite...
### 模式定义 享元模式,运用共享技术,有效地支持大量的细粒度的对象,以避免对象之间拥有相同内容而造成多余的性能开销。 享元(flyweight)模式的主要作用:性能优化,当系统创建过多相似的对象而导致内存占用过高,可以采用这种设计模式进行优化。 享元模式将对象的属性区分为内部状态与外部状态,内部状态在创建的时候赋值,外部状态在实际需要用到的时候进行动态赋值 对于内部状态和外部状态的区分,有几点: 1. 内部状态存储于对象内部 2. 内部状态可以被一些对象共享 3. 内部状态独立于具体场景,通常不会改变 4. 外部状态取决于具体场景,并根据场景变化,外部状态不能被共享。 ### 实战 我们要创建 100 个大小相同颜色不同的 div。 #### 不使用享元模式的做法是: 1. 创建一个创建 div 的类,CreateDiv。 2. new CreateDiv() 创建...
> 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 ### 优缺点 `优点` 1. 可以让任何两个没有关联的类一起运行。 2. 提高了类的复用。 3. 增加了类的透明度。 4. 灵活性好。 `缺点` 1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。 ### 实战 举一个例子,你要写一个页面兼容各个端的小程序,那么你就需要根据环境调用不同小程序的 sdk 方法。比如在支付宝中有一个 `zhifubaoShare` 的分享方法,在微信中有一个 `weixinShare` 的分享方法。(当然一个sdk还有很多方法,我们只拿分享来举例子)但是我们在工作中其实只希望调用一个 `share` 方法就能实现不同端的分享。下面我们用适配器模式来做一个 `Adapter` 适配器。...
> 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。 如果我们把代码编程比作是战争的话,那么设计模式就是兵法。不会兵法肯定打不过会兵法的,即使能打过也要付出更多的代价。 设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 目的:使用设计模式是为了可重用代码,让代码更容易被他人理解、保证代码的可靠性。 ## 单例模式 > 保证一个类仅有一个实例,并提供一个访问它的全局访问点 ### 特点 1. 单例类只能有一个实例。 2. 单例类必须自己创建自己的唯一实例。 3. 单例类必须给所有其他对象提供这一实例。 ### 单例模式场景 - 电脑上的文件,无论在任何地方修改文件,它都只有一份 - 古代的皇帝,也只能有一个 - vue-router 跟 vuex 的 install...
## 工厂模式 ### 目的 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行 ### 使用场景 我们明确地计划不同条件下创建不同实例时 ### 优缺点 `优点` 1. 隐藏了对象创建的细节,将产品的实例化过程放到了工厂中实现。 2. 客户端基本不用关心使用的是哪个产品,只需要知道用工厂的那个方法(或传入什么参数)就行了. 3. 方便添加新的产品子类,每次只需要修改工厂类传递的类型值就行了。 4. 遵循了依赖倒转原则。 `缺点` 1. 适用于产品子类型差不多, 使用的方法名都相同的情况. 2. 每添加一个产品子类,都必须在工厂类中添加一个判断分支(或一个方法),这违背了OCP(开闭原则)。 ### 实现 比如我要有一个 `Animal` 工厂,这个工厂要生产动物。那么我要定义动物都有...