function person(name,age){ var obj = new Object(); obj.name = name; obj.age = age; obj.greet = function(){ return "hello "+this.name; }; return obj } var Adam = person("Adam",18); var Eve = person("Eve",20);
上述工厂模式:
优点:能批量生产结构类似的对象;封装创建对象的细节;
缺点:未能解决对象的类型,即由哪个构造函数创建的;
2.3 构造函数模式
构造函数可以创建特定类型的对象,类似之前的Array、RegExp等原生对象都能创造特定类型的实例对象;
function Person(name,age){ this.name = name; this.age = age; this.greet = function(){ return "hello "+this.name; } } var p1 = new Person('Adam',18); var p2 = new Person('Eve',20);
使用构造函数模式就能够解决实例对象由谁创建的问题;
上述代码和工厂模式的区别在于:
1.没有显示创建新对象;
2.直接将属性和方法赋给this对象;
3.没有return语句;
4.函数名开头大写以区别普通函数;
5.使用new操作符去创建对象实例;
new操作符的原理
使用new操作符去调用函数和直接调用函数不同,其new操作符的运行函数的过程为:
创建一个新对象;
将构造函数的作用域赋给新对象并执行构造函
内的代码;
返回新对象;
使用代码表示如下:
function Person(name,age){ this.name = name; this.age = age; this.greet = function(){ return "hello "+this.name; } } function createPerson(name,age){ var o = new Object(); Person.call(o,name,age); return o; } var p1 = createPerson('Adam',18); var p2 = createPerson('Eve',20);
使用构造函数模式创建对象的优缺点在于:
优点:能够识别对象属于的构造函数;
缺点:如果存在不同实例对象共享的属性和方法,使用构造函数模式则会浪费内存;
【注】
关于this关键字的更多知识点可以参见【what's this】;
构造函数如果不用new操作符调用和普通函数是一样的;
2.4 原型模式
每个函数都有一个prototype原型属性,这个原型属性可以部署特定类型的实例共享的属性和方法;
function Person(){} } Person.prototype.greet = function(){ return "hello "+this.name;
将原来的greet函数部署在Person函数的prototype原型属性上,这样p1和p2可以共享该方法,而不像构造函数模式每创建一个实例就增加一个greet方法浪费内存;