構(gòu)造函數(shù)模式的目的:是為了創(chuàng)建一個(gè)自定義類,并且創(chuàng)建這個(gè)類的實(shí)例
構(gòu)造函數(shù)模式與工廠模式區(qū)別:
1、執(zhí)行的時(shí)候:
普通函數(shù)執(zhí)行:函數(shù)名();eg:var p1=date();
構(gòu)造函數(shù)模式執(zhí)行:new 函數(shù)名(); eg:var p1=new Date(); (通過new執(zhí)行后,函數(shù)名就不是函數(shù)名了,是一個(gè)類了),函數(shù)執(zhí)行的返回值(p1)是Date這個(gè)類的一個(gè)實(shí)例。
JS中所有的類都是函數(shù)數(shù)據(jù)類型的,所有的實(shí)例都是對(duì)象數(shù)據(jù)類型的
2、在函數(shù)代碼執(zhí)行的時(shí)候:
相同:都是形成一個(gè)新的私有作用域,然后形參賦值--->預(yù)解釋---->代碼從上到下執(zhí)行(類和普通函數(shù)一樣,既有普通函數(shù)具有的,也有自己的)
不同:在代碼執(zhí)行之前,不用再自己手動(dòng)的創(chuàng)建對(duì)象了,瀏覽器會(huì)默認(rèn)的創(chuàng)建一個(gè)對(duì)象的數(shù)據(jù)類型的值(這個(gè)對(duì)象就是我們當(dāng)前類的一個(gè)實(shí)例)。--- 接下來代碼從上到下執(zhí)行,以當(dāng)前實(shí)例為執(zhí)行主體(this代表的是當(dāng)前的實(shí)例),然后分別把屬性名和屬性值賦值給當(dāng)前實(shí)例。---最后瀏覽器會(huì)默認(rèn)的把創(chuàng)建實(shí)例返回。
在構(gòu)造函數(shù)模式中,類中(函數(shù)體中)出現(xiàn)的this.xxx=xxx中的this是當(dāng)前類的一個(gè)實(shí)例。
假設(shè)p1和p2是一個(gè)類的兩個(gè)實(shí)例,都有該類中其中的方法,但是不同實(shí)例之間的方法是不一樣的。因?yàn)閮蓚€(gè)實(shí)例互不相關(guān),都是獨(dú)立個(gè)體,而方法為各自實(shí)例的私有屬性,所以是不同的(不相等的)。
——————————————————————————————————
擴(kuò)展:
1、在構(gòu)造函數(shù)模式中new Fn()執(zhí)行,如果Fn不需要傳遞參數(shù)的話,后面小括號(hào)可省略(類名一般第一個(gè)單詞首字母大寫)
2、this的問題:在類中出現(xiàn)的this.xxx=xxx中的this都是是當(dāng)前類的實(shí)例,而某一個(gè)屬性值(方法),方法中的this需要看方法執(zhí)行的時(shí)候,前面是否有“.”才能知道this是誰
3、類有普通函數(shù)具有的,當(dāng)函數(shù)執(zhí)行的時(shí)候,eg:var num其實(shí)只是當(dāng)前形成的私有作用域中的私有變量而已,和f1這個(gè)實(shí)例沒有任何關(guān)系;只有this.xxx=xxx才相當(dāng)于給f1這個(gè)實(shí)例加私有的屬性和方法,才和f1有關(guān)。eg:
function Fn(){
var num=10;
this.x=100;
}
var f1=new Fn;
4、在構(gòu)造函數(shù)模式中,瀏覽器會(huì)默認(rèn)的把實(shí)例返回(返回的是一個(gè)對(duì)象數(shù)據(jù)類型的值);如果自己手動(dòng)寫一個(gè)return返回:
(1).返回的是一個(gè)基本數(shù)據(jù)類型的值的話,eg:return 10;當(dāng)前實(shí)例是不變的,f1返回的還是Fn類的實(shí)例
(2).返回的是一個(gè)引用數(shù)據(jù)類型的值的話,當(dāng)前實(shí)例會(huì)被自己寫的return值給替換掉,eg:return {name:“趙四”},f1返回的就不是Fn的實(shí)例了,而是對(duì)象{name:“趙四”}
5、檢測(cè)某一個(gè)實(shí)例是否屬于這個(gè)類用instanceof,屬于返回true,反之false。也可以用來檢測(cè)數(shù)據(jù)類型(因?yàn)閠ypeof檢測(cè)數(shù)據(jù)類型時(shí)不能細(xì)分object下的對(duì)象、數(shù)組、正則等,而instanceof可以)
6、若f1和f2都是Fn這個(gè)類的一個(gè)實(shí)例,都擁有x這個(gè)屬性,但這個(gè)屬性是各自實(shí)例的私有屬性,即console.log(f1.x===f2.x); //---->false
in:檢測(cè)某一個(gè)屬性是否屬于這個(gè)對(duì)象(attr in object),不管是私有屬性還是公有屬性。只要存在,用in檢測(cè)都是true,即console.log("x" in f1); //----->true是它的一個(gè)屬性
hasOwnProperty:用來檢測(cè)某屬性是否為這個(gè)對(duì)象的私有屬性,并只能檢測(cè)私有屬性,即console.log(f1.hasOwnProperty("x")); //----->true,x是f1的私有屬性