第一部分:基础知识

97 阅读6分钟
JavaScript 没有提供传统面向对象语言中的类式继承,而是通过原型委托的方式来实现对象与对象之间的继承。
鸭子类型指导我们只关注对象的行为,而不关注对象本身,也就是关注 HAS-A, 而不是 IS-A。利用鸭子类型的思想,我们不必借助超类型的帮助,就能轻松地在动态类型语言中实现一个原则:“面向接口编程,而是面向实现编程”。
在静态类型语言中,要实现“面向接口编程”并不是一件容易的事情,往往要通过抽象类或者接口等将对象进行向上转型。当对象的真正类型被隐藏在它的超类型身后,这些对象才能在类型检查系统的“监视”之下互相被替换使用。只有当对象能够被互相替换使用,才能体现出对象多态性的价值。
多态的实际含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来。
静态语言类型检查带来的安全性的同时,我们亦会感觉被束缚住了手脚。为了解决这一问题,静态类型的面向对象语言通常被设计为可以向上转型:当给一个类变量赋值时,这个变量的类型既可以使用这个类本身,也可以使用这个类的超类。
当 Duck 对象和 Chicken 对象的类型都被隐藏在超类型 Animal 身后,Duck 对象和 Chicken对象就能被交换使用,这是让对象表现出多态性的必经之路,而多态性的表现正是实现众多设计模式的目标。
使用继承来得到多态效果,是让对象表现出多态性的最常用手段,继承通常包括实现继承和接口继承。
JavaScript作为一门动态类型语言,它在编译时没有类型检查的过程,既没有检查创建的对象类型,又没有检查传递的参数类型。既可以往makeSound函数种传递duck对象,亦可以传递chicken对象当作参数,由此可见,某一种动物能否发出叫声,只取决于它是否具有makeSound方法,而不取决于它是否是某种类型的对象。这样就不存在任何程度上的“类型耦合”。所以在JS中,并不需要诸如向上转型之类的技术来取得多态的效果。
Martin Fowler:多态的最根本好处在于,你不必再向对象询问“你是什么类型”,而后根据得到的答案调用对象的某个行为——你只管调用该行为就是了,其他一切多态机制都会为你安排妥当。换句话说,多态最根本的作用就是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。将行为分布在各个对象中,并让这些对象各自负责自己的行为,这正是面向对象设计的优点。
封装:封装的目的是将信息隐藏,在许多语言的对象系统中,封装数据是由语法解析来实现的,这些语言也许提了 privatepublicprotected 等关键字来提供不同的访问权限。但 JavaScript 并没有提供对这些关键字的支持,我们只能依赖变量的作用域来实现封装特性,而且只能模拟出 publicprivate 这两种封装性。
封装的目的是将信息隐藏,封装应该被视为“任何形式的封装”,也就是说,封装不仅仅是隐藏数据,还包括隐藏实现细节、设计细节以及隐藏对象的类型等。从封装实现细节来讲,封装使得对象内部的变化对其他对象而言是透明的,也就是不可见的。对象对它自己的行为负责。其他对象或者用户都不关心它的内部实现。封装使得对象之间的耦合变松散,对象之间只通过暴露的 API 接口来通信。当我们修改一个对象时,可以随意地修改它的内部实现,只要对外的接口没有变化,就不会影响到程序的其他功能。
封装类型是静态类型语言中一种重要的封装方式。一般而言,封装类型是通过抽象类和接口来进行的。把对象的真正类型隐藏在抽象类或者接口之后,相比对象的类型,客户更关心对象的行为。
23种设计模式分别被划分为创建型模式、结构型模式和行为型模式:创建型模式的目的就是封装创建对象的变化、结构型模式封装的是对象之间的组合关系、行为型模式封装的是对象的行为变化。
原型编程范式至少包含以下几个原则:
    1、所有的数据都是对象
    2、要得到一个对象不是通过类实例化,而是找到一个对象作为原型并克隆它(js中的对象都是从Object.prototype对象克隆而来的,Object.prototype 对象就是它们的原型)
    3、对象会记住它的原型
    4、如果对象无法响应某个请求,它会把这个请求委托给它自己的原型

JavaScript 的 this 总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。 过程与数据的结合是形容面向对象中的“对象”时经常使用的表达。对象以方法的形式包含了过程,而闭包则是在过程中以环境的形式包含了数据。 命令模式的意图是把请求封装为对象,从而分离请求的发起者和请求的接收者(执行者)之间的耦合关系。在命令被执行之前,可以预先往命令对象中植入命令的接收者。