javascript工厂模式
为什么我们要使用工厂模式
1.为了减少代码的冗余
字面量创建一个personl对象
var person = {
name:'zhangsan',
age: 19,
gender:'male',
top:'175cm'
sayName:function(){
console.log(this.name)
}
当我们需要创建多个person时,且拥有同样的属性,我们要重复很多次这样的代码操作,这就造成大量的代码重复,这时使用工厂模式,我们就能减少代码冗余问题。
使用工厂模式创建personl对象
function person(name,age,gender,top){
person.name = name;
person.age = age;
person.gender = gender;
person.top = top;
person.sayName = function(){
console.log(this.name)
}
return person;
}
var person1 = person('张三',19,'male','175cm');
var person1 = person('李四',18,'female','173cm');
如上代码所示,当我们封装好personl这个工厂时,也是就定义一个personl函数,只要我们把参数(相当于原料)传入进去,我们只用一行代码量就可以把一个personl对象创建出来,非常明显的减少了代码量。
但是 工厂模式的本质是对创建对象的过程进行了封装,本质上没有改变,我们在用工厂模式创建personl对象时,无法知道其具体的数据类型,比如我们创建一个String的数据类型,我们就知道它是一个String类型,但是我们创建personl对象时,无法知道他是personl对象还是dog或bird对象,仅仅只知道是一个对象。
构造函数模式
ECMAScript 中的构造函数是用于创建特定类型对象的。像 Object 和 Array 这样的原生构造函数,运行时可以直接在执行环境中使用。当然也可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。
JavaScript也可以自己自定义构造函数
function Person(name,age,gender,top){
this.name = name;
this.age = age;
this.gender = gender;
this.top = top;
this.sayName = function(){
console.log(this.name)
}
}
var person1 = new Person('张三',19,'male','175cm')
var person2 = new Person('李四',19,'female','173cm')
当我们使用自定义构造函数创建person对象时,我们就能很清楚的明白其数据类型是一个Person对象,person1 和 person2 分别保存着 Person 的不同实例。所有对象都会从它的原型上继承一个 constructor
属性,这两个对象的constructor 属性指向 Person 。 实际上,Person()内部的代码跟 person()基本是一样的,只是有如下区别
1.没有return 返回值;
2.属性和方法直接赋值给了 this。
3.没有显式地创建对象。
而且 在创建自定义构造函数时,函数名第一个字母需要大写,默认为构造函数,小写默认为普通函数。
console.log(person1.constructor === Person); // true
console.log(person2.constructor === Person); // true
工厂模式和构造函数模式对比
在输出person1时,工厂模式输出只仅仅知道是一个对象,不明白是什么实例对象,而构造函数输出明显能知道是一个Person实例对象
工厂模式输出
打印person1和person2输出的是一个对象
构造函数模式输出
构造函数模式输出,很明显看出是一个Person实例对象。
然而我们使用构造函数在定义内部函数或方法时,我们每次定义一个person时,person里面的函数就会被重新定义,这样我们还是产生代码冗余问题。
那么我们要怎么去改变这种情况呢?
- 我们可以在外部定义一个sayName函数,即全局函数,让Person在内部调用,这样就不会出行函数重复定义问题了
在我们使用这种模式之时,新的问题也随之而来,当我们Person需要拥有很多方法的时候,我们需要在外部定义大量的函数给予Person使用,这会导致自定义类型引用的代码不能很好地聚集一起。
这个新问题可以通过原型模式来解决。
原型模式
function Person(){}
Person.prototype.name = "zhangsan";
Person.prototype.age = 29;
Person.prototype.gender = "male";
Person.prototype.sayName = function () {
console.log(this.name);
};
var person1 = new Person();
person1.sayName(); // zhangsan
var person2 = new Person();
person2.sayName(); // zhangsan
console.log(person1.sayName == person2.sayName); // true
使用原型模式,我们就能解决函数冗余问题和函数重复定义问题