Javascript學(xué)習(xí)筆記之函數(shù)篇(五) : 構(gòu)造函數(shù)
Javascript 中的構(gòu)造函數(shù)與其他語(yǔ)言相比也是不同的。任何通過(guò)關(guān)鍵字 new 調(diào)用的函數(shù)都可以當(dāng)做構(gòu)造函數(shù)。
在構(gòu)造函數(shù)體內(nèi),this 指向新創(chuàng)建的對(duì)象。如果構(gòu)造函數(shù)體內(nèi)沒(méi)有顯示的 return 表達(dá)式,那么我們就默認(rèn)返回 this,也就是新建的對(duì)象。
function Foo() {
this.bla = 1;
}
Foo.prototype.test = function() {
console.log(this.bla);
};
var test = new Foo();
上面的代碼將 Foo 作為構(gòu)造函數(shù)進(jìn)行調(diào)用,并將新建對(duì)象的原型(__proto__)指向了 Foo.prototype。
如果我們?cè)跇?gòu)造函數(shù)內(nèi)定義返回的 return 表達(dá)式,構(gòu)造函數(shù)就會(huì)返回整個(gè)表達(dá)式,但這個(gè)返回表達(dá)式必須為一個(gè)對(duì)象。
function Bar() {
return 2;
}
new Bar(); // a new object
function Test() {
this.value = 2;
return {
foo: 1
};
}
new Test(); // the returned object
如果 new 被省略,那么函數(shù)將不能返回一個(gè)新的對(duì)象。
function Foo() {
this.bla = 1; // gets set on the global object
}
Foo(); // undefined
上面的例子可能在某些場(chǎng)景下也可以運(yùn)行,但由于 Javascript 中 this 的工作機(jī)制,這里 this 將指向全局對(duì)象。
工廠模式
為了能夠不使用關(guān)鍵字 new,構(gòu)造函數(shù)將不得不顯示返回一個(gè)值。
function Bar() {
var value = 1;
return {
method: function() {
return value;
}
}
}
Bar.prototype = {
foo: function() {}
};
new Bar();
Bar();
上例中使不使用 new 來(lái)調(diào)用函數(shù) Bar 達(dá)到的效果是一樣的,將會(huì)返回一個(gè)新建的包含 method 方法的對(duì)象,這里實(shí)際上就是一個(gè)閉包。
這里需要注意一點(diǎn),new Bar() 將不會(huì)返回 Bar.prototype,而是在 return 表達(dá)式內(nèi)函數(shù) method 的原型對(duì)象。
上例中,使用 new 與否在功能上是無(wú)差異的。
通過(guò)工廠模式創(chuàng)建新的對(duì)象
我們經(jīng)常被提醒不要使用 new,因?yàn)橐坏┩浟怂氖褂脤?dǎo)致錯(cuò)誤。
為了創(chuàng)建一個(gè)對(duì)象,我們更愿意使用工廠模式并在工廠模式內(nèi)構(gòu)造一個(gè)新的對(duì)象。
function Foo() {
var obj = {};
obj.value = 'blub';
var private = 2;
obj.someMethod = function(value) {
this.value = value;
}
obj.getPrivate = function() {
return private;
}
return obj;
}
盡管上例代碼比使用 new 時(shí)更不容易出錯(cuò),而且在使用私有變量時(shí)將更加方便,但同時(shí)也有一些不好的地方:
因?yàn)椴荒芄蚕碓蛯?duì)象,所以需要更多的內(nèi)存。
為了實(shí)現(xiàn)繼承,工廠模式需要拷貝另一個(gè)對(duì)象的所有方法或者將其作為新對(duì)象的原型。
放棄原型鏈只是為了避免使用 new,這似乎與 Javascript 語(yǔ)言的精神相悖。
總結(jié)
盡管使用 new 可能比較容易產(chǎn)生錯(cuò)誤,但這并不能成為放棄使用原型鏈的原因。至于最后采取哪種方式,這需要根據(jù)應(yīng)用的需求而定。最好的方式就是選擇一種風(fēng)格并堅(jiān)持下去。
簡(jiǎn)單的說(shuō)構(gòu)造函數(shù)就是初始化一個(gè)實(shí)例對(duì)象,對(duì)象的prototype屬性是繼承一個(gè)實(shí)例對(duì)象。
相關(guān)文章
淺析js中2個(gè)等號(hào)與3個(gè)等號(hào)的區(qū)別
這篇文章介紹了js中2個(gè)等號(hào)與3個(gè)等號(hào)的區(qū)別,有需要的朋友可以參考一下2013-08-08通過(guò)正則表達(dá)式獲取url中參數(shù)的簡(jiǎn)單實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇通過(guò)正則表達(dá)式獲取url中參數(shù)的簡(jiǎn)單實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06使用Math.floor與Math.random取隨機(jī)整數(shù)的方法詳解
本篇文章對(duì)使用Math.floor與Math.random取隨機(jī)整數(shù)的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05舉例講解如何判斷JavaScript中對(duì)象的類(lèi)型
這篇文章主要介紹了如何判斷JavaScript中對(duì)象的類(lèi)型,舉例講解了使用typeof和instanceof等操作符來(lái)進(jìn)行判斷的方法,需要的朋友可以參考下2016-04-04