读书笔记-JavaScript设计模式-01面向对象的JavaScript
声明:本文更多的是对于笔者在上下班途中看书📖的书摘,基本上都是自己在微信读书上标注出来然后导出的,个别地方会加入些自己的理解,书名叫做《JavaScript的设计模式与开发实践》
,感兴趣的可以自己购入哈,大佬可绕道。
1.面向对象的JavaScript
JavaScript
没有提供传统面向对象语言中的类式继承,而是通过原型委托
的方式来实现对象与对象
之间的继承。
1.1 动态类型语言和鸭子类型:
-
静态类型语言在编译时便已确定变量的类型
,而动态类型语言的变量类型要到程序运行的时
候,待变量被赋予某个值之后,才会具有某种类型。 -
动态类型语言的缺点是无法保证变量的类型,从而在程序的运行期有可能发生跟类型相关的错误。
-
鸭子类型
:如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子。
1.2 多态:
多态的实际含义
:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。
多态的思想
实际上是把“做什么”和“谁去做”分离开来,要实现这一点,归根结底先要消除类型之间的耦合关系。对象的多态性
提示我们,“做什么”和“怎么去做”是可以分开的
1.3 封装:
作用域创建
: 除了ECMAScript 6
中提供的let
之外,一般我们通过函数来创建作用域
描述的封装
:指的是数据层面
的封装。有时候我们喜欢把封装等同于封装数据封装的目的
:是将信息隐藏,封装应该被视为“任何形式的封装”,也就是说,封装不仅仅是隐藏数据,还包括隐藏实现细节、设计细节以及隐藏对象的类型等- **
迭代器的作用
:**是在不暴露一个聚合对象的内部表示的前提下,提供一种方式来顺序访问这个聚合对象 - 封装类型是通过抽象类和接口来进行的
- 封装:
创建型模式
:目的就是封装创建对象的变化。结构型模式
:封装的是对象之间的组合关系。行为型模式
:封装的是对象的行为变化。
1.4 原型模式和基于原型继承的JavaScript对象系统:
JavaScript
本身是一门基于原型的面向对象语言,它的对象系统就是使用原型模式
来搭建的,在这里称之为原型编程范型也许更合适
-
原型模式不单是一种设计模式,也被称为一种编程泛型。
-
ECMAScript 5
提供了Object.create
方法,可以用来克隆对象
-
依赖倒置原则提醒我们创建对象的时候要避免依赖具体类
-
基于原型链的委托机制
就是原型继承的本质 -
JavaScript
中的根对象
是Object.prototype
对象
JavaScript的函数
既可以作为普通函数被调用
,也可以作为构造器被调用
。
当使用new运算符来调用函数时
,此时的函数就是一个构造器
。
用new运算符来创建对象
的过程,实际上也只是先克隆Object.prototype对象,再进行一些其他额外操作的过程。
-
__protp__
:JavaScript
给对象提供了一个名为__proto__
的隐藏属性
,某个对象的__proto__
属性默认会指向它的构造器的原型对象,即{Constructor}.prototype
-
对象的访问
:如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型 -
**
通过原型来完成能力借用
:**当对象a需要借用对象b的能力时,可以有选择性地把对象a的构造器的原型
指向对象b
,从而达到继承的效果。 -
设计模式是对语言不足的补充
,如果要使用设计模式,不如去找一门更好的语言。 -
Object.create
就是原型模式的天然实现 -
除了根对象Object.prototype本身之外,任何对象都会有一个原型
。而通过Object.create( null )
可以创建出没有原型的对象。
//在Chrome 和Firefox 等向外暴露了对象__proto__属性的浏览器下,我们可以通过下面这段代码来理解new 运算的过程:
function Person( name ){
this.name = name;
};
Person.prototype.getName = function(){
return this.name;
};
var objectFactory = function(){
var obj = new Object(), // 从Object.prototype 上克隆一个空的对象
Constructor = [].shift.call( arguments ); // 取得外部传入的构造器,此例是Person
obj.__proto__ = Constructor.prototype; // 指向正确的原型
var ret = Constructor.apply( obj, arguments ); // 借用外部传入的构造器给obj 设置属性
return typeof ret === 'object' ? ret : obj; // 确保构造器总是会返回一个对象
};
var a = objectFactory( Person, 'sven' );
console.log( a.name ); // 输出:sven
console.log( a.getName() ); // 输出:sven
console.log( Object.getPrototypeOf( a ) === Person.prototype ); // 输出:true