面向?qū)ο?br>
* 單利模式
* 工廠模式
* 構(gòu)造函數(shù)模式
* 原型模式
* call,apply,bind
* 繼承
面向?qū)ο?/p>
對(duì)象:指的是基于對(duì)象 類 實(shí)力來研究的
類:是對(duì)對(duì)象的具體細(xì)分
實(shí)例:某一個(gè)類別種具體的事物
對(duì)象的特征:屬性 方法
面向?qū)ο蟮奶攸c(diǎn)
面向?qū)ο笏枷胍步校╫o思想 oop思想)
1:封裝:對(duì)同一個(gè)功能的函數(shù),只能封裝一次,以后遇到此功能只需要調(diào)用即可,無需重寫。避免大量亢余代碼:低耦合,高內(nèi)聚(單利模式 工廠模式 構(gòu)造函數(shù)模式 原型模式)
2:繼承:子類可以繼承父類的屬性跟方法
3:多態(tài):多種形態(tài) ?重寫 重載
重載:js沒有嚴(yán)格意義上的重載,有類似的功能,傳不同的參數(shù),可以實(shí)現(xiàn)不同的功能
重寫:子類可以重寫父類的屬性和方法
單利模式
單例模式
1:單例模式;把描述同一個(gè)對(duì)象的屬性和方法,都放在同一個(gè)命名空間下避免全局變量的污染
和沖突
單利模式,解決了變量沖突,實(shí)現(xiàn)了分類分組
命名空間: 在單利模式中,我們的對(duì)象名叫做命名空間,單利模式把實(shí)現(xiàn)和描述同一件事物的屬性和方法進(jìn)行分類歸納,然后匯總的同一個(gè)命名空間下,不同的命名空間互不沖突
把描述這個(gè)對(duì)象的屬性跟方法,所存放的空間,起個(gè)名字
2:單利模式的本質(zhì);普通對(duì)象
模塊化開發(fā);單利模式就是最簡單的模塊化開發(fā)
對(duì)于一個(gè)大型的項(xiàng)目,會(huì)分配給不同的工程師,進(jìn)行同步開發(fā);等所有人都開發(fā)完成之后,最后
進(jìn)行代碼合并
3:關(guān)于單利模式的優(yōu)缺點(diǎn)
1 優(yōu)點(diǎn):單利模式可以避免全局變量的污染和沖突
2;單利模式是最簡單的模塊開發(fā)
1)本模塊之間的相互調(diào)用 ;this.屬性名
2)不同模塊之間的相互調(diào)用;模塊名.屬性名
2 缺點(diǎn):會(huì)存在大量的大量亢余代碼
4:解決措施;工廠模式
這三種都是單例模式
1:var personRender={};
2:var studentRender=(function{
return {}
})()
3:function Person(){ } ?var p=new Person()
工廠模式
工廠模式的本質(zhì)-封裝
1;引進(jìn)原材料 ? ? 創(chuàng)建一個(gè)空對(duì)象{} new Object()
2;加工 ? ? ? ? ?給對(duì)象添加屬性和方法
3;輸出產(chǎn)品 ? ? ? 輸出已經(jīng)加工后的對(duì)象;
5;如果想讓工廠模式的調(diào)用方式,跟系統(tǒng)類的調(diào)用方式一樣需要做兩步
1)首字母大寫
2)添加new
構(gòu)造函數(shù)模式
函數(shù):
object 和function 都有一個(gè)自帶的name值指向自己
length是形參的個(gè)數(shù)
構(gòu)造函數(shù)跟工廠模式的區(qū)別
1)類調(diào)用的時(shí)候;
(1)工廠模式是普通函數(shù)的調(diào)用 person()
普通函數(shù)執(zhí)行的時(shí)候沒返回值,那么是undefined
(2)構(gòu)造函數(shù);new首字母大寫() new person
構(gòu)造函數(shù)執(zhí)行的時(shí)候,沒返回值,那么是person{} 這個(gè)對(duì)象
構(gòu)造函數(shù)模式執(zhí)行:
- 1:創(chuàng)建一個(gè)私有作用域 - 進(jìn)行形參賦值- 預(yù)解釋
- 2:new 這樣執(zhí)行,在預(yù)解釋完成后,瀏覽器默認(rèn)的在私有作用域中,創(chuàng)建一個(gè)對(duì)象,函數(shù)中this指向這個(gè)對(duì)象
- 3:在和普通函數(shù)一樣,代碼從上到下執(zhí)行
- 4:new這樣執(zhí)行,在代碼執(zhí)行完成之后,會(huì)默認(rèn)的把第二步種(沒有return也會(huì)默認(rèn)返回一個(gè)對(duì)象),我們創(chuàng)建的這個(gè)對(duì)象返回
2)函數(shù)體內(nèi)的不同
工廠模式(普通函數(shù));三步 1)創(chuàng)建對(duì)象 2)加工對(duì)象 3)返回對(duì)象
構(gòu)造函數(shù);一步加工對(duì)象
7)關(guān)于構(gòu)造函數(shù)的小細(xì)節(jié)
1;構(gòu)造函數(shù)的this都是實(shí)例
2;構(gòu)造函數(shù)中存放的都是私有的屬性和方法
3;實(shí)例只跟構(gòu)造函數(shù)種的this.xxx有關(guān),跟var沒任何關(guān)系
4;構(gòu)造函數(shù)中,系統(tǒng)默認(rèn)為我們創(chuàng)建一個(gè)實(shí)例,并且默認(rèn)返回一個(gè)實(shí)例
5:通過構(gòu)造函數(shù)創(chuàng)建出來的實(shí)例都是相互獨(dú)立的個(gè)體,互不影響,而在構(gòu)造函數(shù)體中寫的this,xx=xx 都相當(dāng)于給當(dāng)前實(shí)例增加自己的私有屬性
不建議自己手動(dòng)返回對(duì)象,如果非要手動(dòng)返回的話 return ?構(gòu)造函數(shù)最好不要寫return
1)返回的是基本數(shù)據(jù)類型,無效,實(shí)例該有的屬性和方法仍然有
2)返回的是引用數(shù)據(jù)類型,以前給實(shí)例添加的屬性和方法都無效了
8;構(gòu)造函數(shù);實(shí)例和類打交道
9; new Student() new Student這個(gè)new出來的實(shí)例都會(huì)執(zhí)行 在new一個(gè)實(shí)例的時(shí)候,如果不需要傳參()可以省略
10;學(xué)習(xí)構(gòu)造函數(shù)的目的
1)了解系統(tǒng)類的構(gòu)成
2)自己定義一個(gè)類,并且創(chuàng)建一個(gè)實(shí)例;
11: 類是函數(shù)數(shù)據(jù)類型
實(shí)例是對(duì)象數(shù)據(jù)類型
原型模式
原型模式的基礎(chǔ)知識(shí):
1.每個(gè)函數(shù)數(shù)據(jù)類型(普通函數(shù),類(內(nèi)置類,自定義類)構(gòu)造函數(shù))上,都有一個(gè)屬性,
叫做prototype,prototype是個(gè)原型;他的屬性值是個(gè)對(duì)象
2.prototype這個(gè)對(duì)象上,存放的都是公有的屬性和方法,
他天生自帶一個(gè)屬性
constructor(構(gòu)造函數(shù)),指向當(dāng)前這個(gè)構(gòu)造函數(shù);
3.每個(gè)對(duì)象數(shù)據(jù)類型(實(shí)例,prototype,普通對(duì)象)上,
都有一個(gè)屬性叫做__proto__,指向當(dāng)前實(shí)例所屬類的原型;
14)Object.prototype上的方法:
in驗(yàn)證某一個(gè)屬性是否屬于這個(gè)對(duì)象,不管是私有的還是公有的,只要有,返回的結(jié)果都是true
hasOwnProperty():
判斷是否為對(duì)象的私有屬性
obj1.isPrototypeOf(obj2) :obj1是否在obj2的原型鏈上;
propertyIsEnumerable:是否為可枚舉的屬性
15)__proto__原型鏈:
如果想查找:對(duì)象.屬性名
1)先看該對(duì)象的私有空間中是否有,如果有,說明這個(gè)屬性是私有屬性;
2)如果沒有,通過__proto__繼續(xù)往當(dāng)前實(shí)例所屬類的原型上找,找到了,說明是公有屬性;
3)找不到繼續(xù)通過__proto__一直往上找,找到基類Object.prototype原型上,還沒有的話undefined;
__proto__原型鏈this:
他們的this指向不同,但是查到找的結(jié)果都一樣
p1.hasOwnproperty() ? p1
p1.__proto__.hasOwnproperty() ?p1的原型
p1.__proto__.__proto__hasOwnproperty() object
16)
1:所有的函數(shù)數(shù)據(jù)類型,都是
function這個(gè)類的實(shí)例
2:所有的對(duì)象都是object這個(gè)基類的實(shí)例
3)function和object的關(guān)系:
(1)object instanceof function ===>true 所有類都是function這個(gè)類的實(shí)例
(2)function instanceof function ===>true 所有的對(duì)象都是object這個(gè)基類的實(shí)例
(3)object.prototype 是function.prototype的爹 當(dāng)他的身份是函數(shù)的時(shí)候,有prototype
(4)object.prototype是function_proto_的爹 當(dāng)他為對(duì)象的時(shí)候,是有這個(gè)—proto—
4:
函數(shù)的三種角色
(1):普通函數(shù):形成私有作用域-形參賦值-預(yù)解釋-代碼從上到下執(zhí)行 以及內(nèi)存和內(nèi)存的釋放
(2):構(gòu)造函數(shù):實(shí)例 類 原型 —proto—
(3):對(duì)象:跟普通對(duì)象的功能一模一樣
1;在ie瀏覽器下,禁止用戶通過__proto__去修改實(shí)例上公有的屬性和方法
這上ie瀏覽器的自我保護(hù)機(jī)制
2;在所有的瀏覽器下,禁止用戶批量修改,實(shí)例上的公有屬性和方法
但是我們可以通過,類.prototype.xx進(jìn)行一個(gè)個(gè)的修改
一個(gè)個(gè)修改在標(biāo)準(zhǔn)瀏覽器下,有兩種方式
1)實(shí)例.__proto__.屬性名
2)類.prototype.屬性名
3;
- ?鏈?zhǔn)讲僮鳎覀冴P(guān)注的是前一個(gè)函數(shù)執(zhí)行完成的返回值,返回的是個(gè)數(shù)組,后續(xù)就跟數(shù)組的方法,
- 鏈?zhǔn)綄懛ǎ盒枰WC每一次執(zhí)行方法返回的結(jié)果依然是當(dāng)前類的一個(gè)實(shí)例,這樣就可以繼續(xù)調(diào)取原型上的方法了
返回的是個(gè)數(shù)字,后續(xù)就跟數(shù)字的方法
num.toFixed(2)保留小數(shù)個(gè)數(shù)2位
4;應(yīng)有的條件反射
構(gòu)造函數(shù);放的都是私有的屬性和方法
prototype;放的都是共有的屬性和方法
類.prototype自己賦值一個(gè)對(duì)象,
constructor一定會(huì)出問題
5;in判斷某個(gè)屬性是否為對(duì)象私有+公有屬性 ?加引號(hào)
6;數(shù)組去重;
1.思路1;雙重循環(huán)
拿當(dāng)前項(xiàng)跟他后面的每一項(xiàng),如果相同,刪除其中一個(gè),一定要預(yù)防數(shù)組塌陷 ;
2;思路2;創(chuàng)建新數(shù)組
當(dāng)新數(shù)組中沒有重復(fù)的時(shí)候,才給新數(shù)組種放
3;思路3;利用對(duì)象不重名的特性
當(dāng)對(duì)象中沒有該屬性的時(shí)候,賦值為1
當(dāng)對(duì)象中已經(jīng)有了該屬性的時(shí)候,進(jìn)行累加
注意;兩個(gè)條件中,只走一個(gè)1)continue 2)if...else...
7;屬性操作
注意;判斷屬性是否在對(duì)象上,屬性名一定要加引號(hào),否則會(huì)把它當(dāng)作變量,報(bào)錯(cuò)
1;in判斷某個(gè)屬性是否為對(duì)象私有+公有屬性 ?加引號(hào)
2;obj.hasOwnproperty(屬性名)判斷是否有對(duì)象的私有屬性 propertyIsEnumerable也可以用
3;自己封裝;hasOwnproperty;判斷屬性是否為對(duì)象的
8;原型批量設(shè)置
Fn.prototype=
{
手動(dòng)添加一個(gè):constrouctor:Fn
x:10,
y:11,
c:22
}
call,apply,bind
call:
1:call在Function.prototype原型上找:公有屬性和方法
- f1.call(f2);
函數(shù)中沒有this的時(shí)候,
call前面的函數(shù)f1執(zhí)行
- f1.call.call.call.call.call.call.call.call(f2);
-
call(f2) 他先執(zhí)行, ?然后將前面f1.call改成f2.call()執(zhí)行
函數(shù)中沒有this的時(shí)候 f2這個(gè)函數(shù)執(zhí)行
2:f1.call(obj);
嚴(yán)格和非嚴(yán)格
1: 非嚴(yán)格模式下如果
call的第一個(gè)參數(shù),不傳或者傳的是undefined/null,方法種的this是window
2:嚴(yán)格模式下,如果call中第一個(gè)參數(shù)不傳就是undefined,其余call中的第一個(gè)參數(shù)是啥就是啥,如果是null就是null,如果傳的的undefined就是undefined 'use strict'
3:call的第一個(gè)參數(shù),用來改變call前面這個(gè)實(shí)例中的this關(guān)鍵字;
4:call改完this指向,傳完參數(shù)之后,讓call前面的函數(shù)立即執(zhí)行;
3:call的作用改變this指向
call的第一個(gè)參數(shù),用來改變call點(diǎn)前面的函數(shù)中this指向
call的第二個(gè)參數(shù)開始,相當(dāng)于給fn的形參從左往右賦值
1)call,apply,bind區(qū)別:
call apply 都是在改完this指向,傳完參數(shù)之后,讓前面的函數(shù)立即執(zhí)行
區(qū)別;第二個(gè)參數(shù)不同;call從第二個(gè)參數(shù)開始,一個(gè)個(gè)寫參數(shù),
apply;第二個(gè)參數(shù)是個(gè)數(shù)組;
2)bind;
屬于預(yù)處理機(jī)制;先把bind前面的函數(shù)種的this改了,參數(shù)傳了,
然后返回一個(gè)修改后的函數(shù);在需要的時(shí)候,手動(dòng)調(diào)用 ? 函數(shù)執(zhí)行的時(shí)候,他才執(zhí)行
繼承
子類可以繼承父類的屬性跟方法
1:
call繼承
call:把父類的私有的屬性和方法,都繼承給了子類私有的
2;冒充繼承
把父類私有+公有的屬性和方法,都繼承給子類私有的(for var a in f1 )
3;
原型鏈繼承
把父類私有+公有的屬性和方法,都繼承給子類公有的
4;拷貝繼承
call繼承+extend繼承(參數(shù)里面,后面繼承前面的,)
私有繼承私有的,公有繼承公有的
5:混合繼承:子類私有有父類私有的; 子類公有也有父類私有的
原型鏈繼承:把父類私有+公有,都給了子類公有的
call繼承把父類私有的給了子類私有的;
6:混合繼承