通常我们创建一个自定义对象可以使用以下两种方法
- 使用对象字面量
var obj = {name: 'nany', sex: 'female', run: function(){ /* do something */ }}
- 使用构造函数
var obj = new Object()
obj.name = 'nany'
obj.sex = 'female'
以第一种方法为例(为啥不选第二种?就不选第二种!),当我们需要创建100个有run
方法的对象时,那么我们需要这样写:
var person1 = {
name: 'nany',
sex: 'female',
run: function(){
// do something
}
}
var person2 = {
name: 'lily',
sex: 'female',
run: function(){
// do something
}
}
......
var person100 = {
name: 'jack',
sex: 'male',
run: function(){
// do something
}
}
是不是感觉没有爱了?我只有一个run方法想和你一样竟然要写这么多代码,不能忍,为了解决这个写很多遍重复代码的问题,机智的程序员提出了一种设计模式:工厂模式
function createPerson(name, sex){
var person = new Object()
person.name = name
person.sex = sex
person.run = function(){
// do something
}
return person
}
var person1 = createPerson('nany', 'female')
var person2 = createPerson('jack', 'male')
现在你总不会说代码多又重复了吧?每个有不同的属性值又都有run方法,JS之父看我们又是写var 又是return的,为了让我们再少些几行代码,给我们提供了new这个关键字,同时我们使用了this
function Person(name, sex){
this.name = name
this.sex = sex
this.run = function(){
// do something
}
}
var person1 = new Person('nany', 'female')
var person2 = new Person('jack', 'male')
在这里new帮我们做了如下的事情:
- 不用显示的创建对象,因为 new 会帮你做(使用「this」就可以访问到临时对象);
- 直接将属性和方法赋给了this对象
- 不用 return 对象,因为 new 会帮你做;
这个模式被称为构造函数模式,按照惯例,构造函数始终都应该以一个大写字母开头,并且使用new操作符来创建构造函数的实例。
那么问题又来了,我们不需要每次创建对象的时候再重写run方法,因为我们发现
person1.run === person2.run // false
,我们想要person1的run和person2的run是一样的,这样就没必要每次创建person的时候重复创建run方法了,而用原型链可以解决这个问题
Person.prototype = {
run: function(){
// do something
}
}
注意:如果重新给Person.prototype赋值,那么你的 constructor 属性就没了,所以需要这么写
Person.prototype = {
constructor: Person
run: function(){
// do something
}
}
或者这么写
Person.prototype.run = function(){
// do something
}
至此,整个代码是这样的
function Person(name, sex){
this.name = name
this.sex = sex
}
Person.prototype.run = function(){
// do something
}
var person1 = new Person('nany', 'female')
var person2 = new Person('jack', 'male')
这个模式被称为原型模式,在这里new 总共帮我们做了如下的事情:
- 不用显示的创建对象,因为 new 会帮你做(使用「this」就可以访问到临时对象);
- 直接将属性和方法赋给了this对象;
- 不用 return 对象,因为 new 会帮你做;
- 不用绑定原型,new指定原型的名字为 prototype;
参考
- JS 的 new 到底是干什么的?
- JavaScript高级程序设计P138-148