js 设计模式与继承学习
设计模式
创建自定义对象的最简单方式是new 一个object对象,然后给它添加方法与属性
如:
1 var person = new Object();
2 person.name = "张三";
3 person.sayName = function(){
4 alert(this.name);
5 }
//简单创建对象
这种方式有个很大的缺点:复用性太低,实例化一个这样的实体,就得复制上的面的代码。
于是想到了用工厂模式改进它:工厂抽象了创造的具体对象过程,但ECMScript没有类的概念,这让人很纠结,聪明的先行者,发明了一种函数代替它。
function CreatePersonFactory(_name,_age){
var obj = new Object();
obj.name = _name;
obj.age = _age;
obj.sayName = function(){
alert(this.name);
}
return obj;
}
var p1 = CreatePersonFactory("张三",22);
var p2 = CreatePersonFactory("李四",23);
//工厂模式
这种方式虽然解决了复用的问题,但因为无法识对象(无法知道这个对象的类型,因为它统一返回Object的实例对象,如果我想针对某类型进行扩展,就得哭了)。
需求变了,模式只能再改了。构造函数模式就这样诞生了。
function ConstructFun(_name,_age){ this.name = _name; this.age = _age; this.sayName = function(){ alert(this.name); } } var p1= new ConstructFun("stick",22); var p2 = new ConstructFun("dev",23); p1.sayName();p2.sayName(); document.write(p1.constructor == ConstructFun); document.write(p2.constructor == ConstructFun); //constructor是用来识别用户类型。检测对象类型用instanceof,检测值类型用typeof document.write(p1 instanceof ConstructFun); document.write(p2 instanceof Object); //可以通过让方法放到外面来避免每一次都得实例化。 function ConstructFun(_name,_age){ //..... this.sayName = sayName; } function sayName(){ alert(alert.name); }
//构造函数模式
对比工厂与构造两种函数:工厂显示实例化Object并返回它;构造函数它继承Object,显示实例化当前对象,直接将属性与方法赋于this,没有return语句。构造函数:任何以new操作操作符调用,它就是构造函数。
这种方式定义的对象是在Global对象中,(浏览器为window对象)无特殊说明:instanceof和constructor属性终始会假设在全局作用域中查询构造函数。
[]构造函数的问题是每个方法都得实例化一次,对于实现同一功能的方法,完全没有必要。
为什么每个方法都得实例化一下,这是因为EMCScript中的函数是对象,两个方法不是Function同一个实例。虽然通过利用this,关键字把方法放到外面去,可以避免同一方法多次实例化问题的。但是这样一来这个方法就成了全局函数,如此对象有很多方法,就定义很多全局函数,与封装性违背
这时候冒出原型模式来处理这个问题。