通常我們創(chuàng)建一個(gè)自定義對(duì)象可以使用以下兩種方法
- 使用對(duì)象字面量
var obj = {name: 'nany', sex: 'female', run: function(){ /* do something */ }}
- 使用構(gòu)造函數(shù)
var obj = new Object()
obj.name = 'nany'
obj.sex = 'female'
以第一種方法為例(為啥不選第二種?就不選第二種?。?dāng)我們需要?jiǎng)?chuàng)建100個(gè)有run方法的對(duì)象時(shí),那么我們需要這樣寫(xiě):
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
}
}
是不是感覺(jué)沒(méi)有愛(ài)了?我只有一個(gè)run方法想和你一樣竟然要寫(xiě)這么多代碼,不能忍,為了解決這個(gè)寫(xiě)很多遍重復(fù)代碼的問(wèn)題,機(jī)智的程序員提出了一種設(shè)計(jì)模式:工廠(chǎng)模式
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')
現(xiàn)在你總不會(huì)說(shuō)代碼多又重復(fù)了吧?每個(gè)有不同的屬性值又都有run方法,JS之父看我們又是寫(xiě)var 又是return的,為了讓我們?cè)偕傩仔写a,給我們提供了new這個(gè)關(guān)鍵字,同時(shí)我們使用了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幫我們做了如下的事情:
- 不用顯示的創(chuàng)建對(duì)象,因?yàn)?new 會(huì)幫你做(使用「this」就可以訪(fǎng)問(wèn)到臨時(shí)對(duì)象);
- 直接將屬性和方法賦給了this對(duì)象
- 不用 return 對(duì)象,因?yàn)?new 會(huì)幫你做;
這個(gè)模式被稱(chēng)為構(gòu)造函數(shù)模式,按照慣例,構(gòu)造函數(shù)始終都應(yīng)該以一個(gè)大寫(xiě)字母開(kāi)頭,并且使用new操作符來(lái)創(chuàng)建構(gòu)造函數(shù)的實(shí)例。
那么問(wèn)題又來(lái)了,我們不需要每次創(chuàng)建對(duì)象的時(shí)候再重寫(xiě)run方法,因?yàn)槲覀儼l(fā)現(xiàn)
person1.run === person2.run // false,我們想要person1的run和person2的run是一樣的,這樣就沒(méi)必要每次創(chuàng)建person的時(shí)候重復(fù)創(chuàng)建run方法了,而用原型鏈可以解決這個(gè)問(wèn)題
Person.prototype = {
run: function(){
// do something
}
}
注意:如果重新給Person.prototype賦值,那么你的 constructor 屬性就沒(méi)了,所以需要這么寫(xiě)
Person.prototype = {
constructor: Person
run: function(){
// do something
}
}
或者這么寫(xiě)
Person.prototype.run = function(){
// do something
}
至此,整個(gè)代碼是這樣的
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')
這個(gè)模式被稱(chēng)為原型模式,在這里new 總共幫我們做了如下的事情:
- 不用顯示的創(chuàng)建對(duì)象,因?yàn)?new 會(huì)幫你做(使用「this」就可以訪(fǎng)問(wèn)到臨時(shí)對(duì)象);
- 直接將屬性和方法賦給了this對(duì)象;
- 不用 return 對(duì)象,因?yàn)?new 會(huì)幫你做;
- 不用綁定原型,new指定原型的名字為 prototype;