新聞中心
基本概念
在程序里,我們通過使用對象去構(gòu)建現(xiàn)實世界的模型,把原本很難(或不可)能被使用的功能,簡單化并提供出來,以供訪問

成都創(chuàng)新互聯(lián)服務(wù)項目包括涼州網(wǎng)站建設(shè)、涼州網(wǎng)站制作、涼州網(wǎng)頁制作以及涼州網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,涼州網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到?jīng)鲋菔》莸牟糠殖鞘?,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
這段解釋摘抄自MDN,讀起來甚是繞口。
這里我們可以采用填鴨法來理解面向?qū)ο?,大致是說看起來像只鴨子,那么它就是一只鴨子。人與機器不同的是,人類具備主觀意識而機器沒有,一個具備尖尖的嘴,扁扁的腦袋,嘎嘎嘎的叫聲并且還會游泳的生物,那么這便是我們使用對象思想去構(gòu)建了一只鴨子的類。機器不會像人一樣主觀意識去設(shè)想這其實是一只大鵝。
對象的組成
一個基本的對象由若干個數(shù)據(jù)類型組成,往大的類別上劃分的話,可以分為行為和屬性
屬性:所有的數(shù)據(jù)類型都可以認為是對象的屬性(小鴨子的體重,翅膀,腳丫子等等都是屬性)
行為:一般指函數(shù),賦予對象能力(小鴨子會游泳,那么游泳這個行為就是小鴨子的能力)
實例化對象
至此,我們已經(jīng)創(chuàng)建了一只鴨子類,這時候鴨子僅僅是一個初始化狀態(tài),相當(dāng)于被冰封。我們需要將鴨子解封,可使用new關(guān)鍵字實例化鴨子對象。這樣我們便得到一個全新的鴨子對象。
new關(guān)鍵字具體干了啥? 可參考如下代碼:
var obj = {};
//取得該方法的第一個參數(shù)(并刪除第一個參數(shù)),該參數(shù)是構(gòu)造函數(shù)
var Constructor = [].shift.apply(arguments);
//將新對象的內(nèi)部屬性__proto__指向構(gòu)造函數(shù)的原型,這樣新對象就可以訪問原型中的屬性和方法
obj.__proto__ = Constructor.prototype;
//取得構(gòu)造函數(shù)的返回值
var ret = Constructor.apply(obj, arguments);
//如果返回值是一個對象就返回該對象,否則返回構(gòu)造函數(shù)的一個實例對象
return typeof ret === "object" ? ret : obj;
對象中的this
對于this問題,很多初學(xué)者被這個this指向搞得暈頭轉(zhuǎn)向。其實搞懂this我們只需要記住一句話誰在調(diào)用它,它就指向誰,this指向當(dāng)前調(diào)用它的執(zhí)行環(huán)境
經(jīng)典例子:
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2js中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型?;緮?shù)據(jù)類型是按值訪問,引用數(shù)據(jù)類型是按引用訪問。對象將所有的引用放入棧將所有的值放入堆,要獲取一個對象值,需要先獲取對象引用,然后根據(jù)引用找到對應(yīng)的值。如果引用對應(yīng)的值是一個函數(shù),由于函數(shù)是一個單獨的值,可以存在不同的執(zhí)行上下文環(huán)境。那么問題來了,同樣的函數(shù)在不同的環(huán)境下調(diào)用,我們?nèi)绾卧诤瘮?shù)內(nèi)部獲取當(dāng)前執(zhí)行環(huán)境呢?沒錯,this的出現(xiàn)正是為了解決此類場景問題。
總結(jié):一堆屬性和行為聚合到一起便構(gòu)成了一個最基本的對象??赏ㄟ^new關(guān)鍵字來實例化一個對象,由于執(zhí)行環(huán)境的不同,對象內(nèi)部的this指向也不同。在調(diào)用對象方法時,需要注意一下this的指向問題。
對象系統(tǒng)
上面我們提到了,一個基礎(chǔ)對象的構(gòu)成。但是在我們實際開發(fā)當(dāng)中遠遠比這復(fù)雜的多,往往是多層對象的嵌套或者多個對象通過某個映射文件相互關(guān)聯(lián)又或者一個對象繼承自另一個對象... 從而去構(gòu)建一個更龐大的對象世界,解決更復(fù)雜的應(yīng)用場景,我們把這種復(fù)雜對象稱之為 對象系統(tǒng) ,把這種思想稱之為 面向?qū)ο缶幊?/p>
顯式原型(prototype)
概念:每個函數(shù)上都有一個默認的prototype屬性使您有能力向?qū)ο筇砑訉傩院头椒ā?/p>
function people(name) {
this.name = name;
this.say = function () {
console.log(`hello!我是${name}`);
};
}
people.prototype.kungfu = function () {
console.log(`我是${this.name},我會中國功夫`);
};
const qad = new people('秦愛德');
const zs = new people('張三');
console.log(qad);
console.log(qad.say());
console.log(qad.kungfu());
console.log(zs);
console.log(zs.say());
console.log(zs.kungfu());以上代碼創(chuàng)建了一個people構(gòu)造函數(shù),在它內(nèi)部添加了一個name屬性和say方法,在它的原型上添加了一個kungfu方法
如何理解內(nèi)部屬性和原型屬性呢?
這里我們可以借助css樣式來便于理解
哈哈
以上我們創(chuàng)建了一個標簽,并向標簽添加了一個內(nèi)聯(lián)樣式和外部樣式,對齊構(gòu)造函數(shù)的話,內(nèi)聯(lián)樣式對應(yīng)內(nèi)部屬性,是跟隨函數(shù)獨有的,外部樣式對應(yīng)原型屬性,可以是公共的,可在多處使用。
由于每次new一個新的構(gòu)造函數(shù),內(nèi)部屬性都會重新生成,而原型屬性則不會,所以這也避免了內(nèi)存上的浪費。并且可以基于原型實現(xiàn)原型繼承操作。
構(gòu)造器(constructor)
概念:每個對象都會默認一個contructor,并指向當(dāng)前原型對象的構(gòu)造函數(shù)。
console.log(qad.__proto__.constructor === people); // true
一圖勝千言
總結(jié):每個函數(shù)上都會自帶一個prototype原型,在原型上添加的屬性可以共用,函數(shù)即對象,對象自帶屬性constructor指向了這個構(gòu)造函數(shù)
隱式原型(proto)
概念:每個對象都有一個_proto_屬性,指向了創(chuàng)建該對象的構(gòu)造函數(shù)的原型。
console.log(qad.__proto__ === people.prototype); // true
萬事萬物皆對象,函數(shù)也是一個對象,只要是對象,就擁有_proto_屬性,所以_proto_在構(gòu)造器和原型之間建立了一個連接,通過由內(nèi)向外在構(gòu)造器中找到原型的屬性和方法。
原型鏈
當(dāng)我們創(chuàng)建了一個構(gòu)造函數(shù),并訪問里面的某一個屬性時。會先從構(gòu)造函數(shù)自身去找,再從顯式原型(prototype)上去找,再從隱式原型(__proto__)上去找,再從object的__proto__上去找,直到null。有值就返回相應(yīng)的值,沒有就返回undefined,我們把這個由內(nèi)向外的查找過程稱之為原型鏈
一圖勝千言
用好面向?qū)ο笏枷?/h2>
上面提到我們可以通過使用對象去構(gòu)建現(xiàn)實世界的模型,并將復(fù)雜問題簡單化。要想運用好面向?qū)ο笏枷?,我們需要牢記面向?qū)ο蟮娜筇卣骱蛶讉€原則
三大特征
1:封裝
中華文化博大精深,將詞語拆分之后,發(fā)現(xiàn)更好理解了
封:封存(將一系列行為、屬性、業(yè)務(wù)邏輯等等封存起來)
裝:包裝(提供一個容器來存放封存起來的代碼,包裝之后,對外輸出)
封裝里面還有一個概念叫做抽象,拆分之后也很好理解(把”像“的東西抽出來)
結(jié)合起來就是:我們把相似雷同的一堆屬性、行為、邏輯抽離出來,存放到一個包裝對象里面,控制好入?yún)⒑统鰠⒈阌谒苏{(diào)用,這就是封裝。
2:繼承
繼:繼續(xù)(繼續(xù)延續(xù)下去)
承:承擔(dān)(承擔(dān)延續(xù)下來的重任,并發(fā)揚光大)
結(jié)合起來就是:子類繼續(xù)沿用父類的行為或?qū)傩?,并合理改造拓展業(yè)務(wù),輸出新的對象。頗有點子承父業(yè),青出于藍的意思。
3:多態(tài)
多:多種
態(tài):狀態(tài) / 形態(tài)
結(jié)合起來就是:同一個實例對象在多種狀態(tài)下有不同的展示形態(tài)
簡單理解就是一個函數(shù)通過入?yún)⒉煌?,可以得到不同的輸出結(jié)果
幾個原則
1:單一職責(zé)原則
一個類或者一個函數(shù)實現(xiàn)功能要單一,不能雜亂無章,越純粹越好。一旦函數(shù)變得不純粹了,內(nèi)部實現(xiàn)多個功能。當(dāng)我們在多處地方使用這個函數(shù)的時候往往會因為不夠純粹而多寫很多兼容代碼。
2:開放封閉原則
一個類在拓展性方便應(yīng)該是保持開放的,對更改性應(yīng)該是封閉的。比如我們封裝了一個函數(shù),應(yīng)該盡量預(yù)留好口子,以便日后新功能迭代,而避免直接更改之前已經(jīng)寫好的代碼。
3:里氏替換原則
里氏替換原則主要是用來約束繼承的,子類可以擴展父類的功能,但不能改變父類原有的功能。如果子類不能完整地實現(xiàn)父類方法,或者父類的某些方法在子類中已經(jīng)發(fā)生“畸變”,則建議斷開父子繼承關(guān)系,采用依賴、聚集、組合等關(guān)系來代替繼承。
4:依賴倒置原則
上層模塊不應(yīng)該依賴于下層模塊,兩者都應(yīng)該依賴其抽象。簡而言之就是面向接口開發(fā),每個類都提供接口或者抽象類,抽象類往往是比較穩(wěn)定的,當(dāng)下層細節(jié)發(fā)生變化時,不應(yīng)該直接影響上層。細節(jié)依賴于抽象,只要抽象不變,程序就不要變化。
5:組合聚合復(fù)用原則
在代碼復(fù)用時,要盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實現(xiàn),其次才考慮使用繼承關(guān)系來實現(xiàn)。
6:高類聚低耦合
顧名思義就是高度類似的東西要聚集起來,低相似的東西不要將它們耦合到一起
js本身就是一門面向?qū)ο缶幊痰恼Z言,在我們的日常開發(fā)中,每時每刻都在享受著面向?qū)ο蠼o我們帶來的編程體驗。
網(wǎng)頁題目:理解了面向?qū)ο螅彝黄屏说卦?,代碼寫的真棒!
標題網(wǎng)址:http://www.dlmjj.cn/article/cdpgiis.html


咨詢
建站咨詢
