当一个项目的代码量比较多,或者多人开发的时候,就需要引入一些设计模式来让我们更好的构建项目。否则代码就会变得乱糟糟,像一团面条一样了。
讲解设计模式比较好的书有:
1、设计模式
2、Head First设计模式
不过以上两本书主要是关于静态语言、面向对象的具体实现,因为静态面向对象语言(比如C++ 和 Java)代码写法限制的是比较多的。不能给类动态的添加属性、方法,函数的参数限制了类型等。
JS 虽然也是面向对象,但是同时支持函数式编程,函数本身是一种值可以传递。JS的动态特性也不会限制变量类型。
所以Java 中的多态对JS 来说,那都不叫事。
对于 JS ,设计模式也应该更加灵活,不应该把静态语言的设计模式生搬硬套到 JS 上,而应该根据语言特性灵活应用。
关于 JS 的设计模式,强力推荐这本书:JavaScript设计模式与开发实践,来自腾讯的大牛所著。
讲解设计模式之前,我们先接触一个重要的概念 鸭子类型
什么叫鸭子类型呢?
需求:如果我们想听鸭子的 嘎嘎嘎 叫声
情况:如果有一只狗(不是鸭子),它也能发出 嘎嘎嘎 的叫声。也就是说这条狗也能达到我们的目的,那这条狗就是可以用的。
思考:我们不再管这个对象到底是不是 instanceof Duck, 而是看它有没有 嘎嘎嘎 叫的能力。就是说我们不再是面向对象,而是面向接口。管它是什么类型,什么对象,只要实现了 嘎嘎嘎 叫的这个接口,能达到我们的目的,就可以了。
举个例子:
// aDiv 不是数组,而是 HTMLCollection 对象
var aDiv = document.getElementsByTagName('div');
// 但是由于 aDiv 也有 length 属性,因此我们可以像数组一样遍历它
for (var i=0, len=aDiv.length; i<len; i++) {
console.log(aDiv[i]);
}
接下来一个重要的概念是 封装
,把一个对象、方法或模块的内部实现隐藏起来,只暴露接口供外部使用。
JS 最常见的是用立即执行函数封装局部变量,局部函数,暴露出部分函数或变量。
// 对 ming 这个对象进行了封装,privateName 只能在立即执行函数的内部使用,外部获取不到的。
var ming = (function() {
// 乳名,外人不知道的
var privateName = '狗蛋';
// 学名
var publicName = '王小明';
var publicAge = 24;
return {
age: publicAge,
getName: function() {
return publicName;
}
};
}());
JS 面向对象采用的是原型克隆方式,而不是 Java 类和对象的模式。
因此 JS 生产对象的方式更像是 细胞分裂
,Object.prototype
作为第一个细胞,然后分裂出 Function.prototype 、Array.prototype 、String.prototype 等,分裂出来的细胞可以添加自己的属性和方法。而且 JS 是没有 类
这个东东的。
Java 中的类像是一个模具,对象则是用这个模具印出来的,
第一篇文先说这么多,后续再把设计模式一一过一遍。最重要的是,推荐大家看看腾讯大牛的书。