摘要:構(gòu)造函數(shù)的兩個(gè)特征函數(shù)內(nèi)部使用了,指向所要生成的對象實(shí)例。將一個(gè)空對象的指向構(gòu)造函數(shù)的屬性,這個(gè)對象就是要返回的實(shí)例對象。用面向?qū)ο箝_發(fā)時(shí),把要生成的實(shí)例對象的特有屬性放到構(gòu)造函數(shù)內(nèi),把共有的方法放到構(gòu)造函數(shù)的里面。
JS中面向?qū)ο蟮母拍?/b>
面向?qū)ο驩OP是一種組織代碼結(jié)構(gòu)、實(shí)現(xiàn)功能過程的思維方式。它將真實(shí)世界各種復(fù)雜的關(guān)系,抽象為一個(gè)個(gè)對象,然后由對象之間的分工與合作,完成對真實(shí)世界的模擬。每一個(gè)對象都是功能中心,具有明確分工,可以完成接受信息、處理數(shù)據(jù)、發(fā)出信息等任務(wù)。
舉例:一本書、一輛汽車、一個(gè)人都可以是對象,一個(gè)數(shù)據(jù)庫、一張網(wǎng)頁、一個(gè)與遠(yuǎn)程服務(wù)器的連接也可以是對象。當(dāng)實(shí)物被抽象成對象,實(shí)物之間的關(guān)系就變成了對象之間的關(guān)系,從而就可以模擬現(xiàn)實(shí)情況,針對對象進(jìn)行編程。對象是單個(gè)實(shí)物的抽象,對象還是一個(gè)容器,封裝了屬性(property)和方法(method)。屬性是對象的狀態(tài),方法是對象的行為(完成某種任務(wù))。比如,我們可以把動(dòng)物抽象為animal對象,使用“屬性”記錄具體是那一種動(dòng)物,使用“方法”表示動(dòng)物的某種行為(奔跑、捕獵、休息等等)。
面向?qū)ο蟮膶?shí)現(xiàn)思路:把某個(gè)功能看成一個(gè)整體(對象),通過調(diào)用對象的某個(gè)方法來啟動(dòng)功能。在用的時(shí)候不去考慮這個(gè)對象內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),在去實(shí)現(xiàn)這個(gè)對象細(xì)節(jié)的時(shí)候不用管誰在調(diào)用。面向?qū)ο蟮姆椒ㄔ谇岸隧撁嬷幸话阌脕韺⒅貜?fù)的東西抽象化,便于復(fù)用和節(jié)省內(nèi)存。
面向?qū)ο蟮娜齻€(gè)要點(diǎn)封裝:就是將類內(nèi)部的機(jī)制隱藏起來,讓外界無法訪問,從而達(dá)到保護(hù)數(shù)據(jù)的目的。封閉一部分讓外界無法訪問,開放一部分,通過開放部分間接訪問私有部分。可以用閉包來實(shí)現(xiàn)JS面向?qū)ο笾接袑傩苑庋b。
繼承:為了提高代碼的復(fù)用性,可以用繼承,將一個(gè)子類繼承一個(gè)父類,這樣子類就可以繼承父類的屬性和方法,而不需要重新寫一個(gè)類中的屬性和方法。JavaScript的繼承方式是通過原型鏈來完成的。
多態(tài):多個(gè)子類中雖然都具有同一個(gè)方法,但是這些子類實(shí)例化的對象調(diào)用這些相同的方法后卻可以獲得不同的結(jié)果。
用傳統(tǒng)的面向?qū)ο笏季S,構(gòu)造實(shí)例的過程近似理解為:JS中object(對象)是某一個(gè)class(類)的實(shí)例,class可以理解成模具,object就是用模具制造出來的實(shí)物。
但JS中沒有類的概念,只有構(gòu)造函數(shù)(函數(shù))、屬性的概念。很多語言中是由類(class)構(gòu)造出實(shí)例對象,但JS中的對象不基于類而構(gòu)建,而是基于構(gòu)造函數(shù)和原型鏈來構(gòu)建的。比如:var ccc={name:"penny"}這種寫法是可行的,JS中本質(zhì)上是通過new Object()這個(gè)構(gòu)造函數(shù)來創(chuàng)建。對象是單個(gè)實(shí)物的抽象。通常需要一個(gè)模板,表示某一類實(shí)物的共同特征,然后對象根據(jù)這個(gè)模板生成。JavaScript 語言使用構(gòu)造函數(shù)(constructor)作為對象的模板。所謂”構(gòu)造函數(shù)”,就是專門用來生成對象的函數(shù)。它提供模板,描述對象的基本結(jié)構(gòu)。一個(gè)構(gòu)造函數(shù),可以生成多個(gè)對象,這些對象都有相同的結(jié)構(gòu)。
通過類構(gòu)建好比是上帝造人類,先定義好人的各屬性當(dāng)作模板,再創(chuàng)建人類
不依賴類構(gòu)建(函數(shù)式編程)好比是人進(jìn)化成人類,在進(jìn)化過程中不斷給人添加各種屬性形成人類。
構(gòu)造函數(shù)的兩個(gè)特征:
[1]函數(shù)內(nèi)部使用了this,指向所要生成的對象實(shí)例。
[2]必須用new命令調(diào)用生成對象實(shí)例
new運(yùn)算符接受一個(gè)函數(shù)及其參數(shù)作為構(gòu)造器,根據(jù)傳入?yún)?shù)來創(chuàng)建相同類型但值不同的實(shí)例對象。new命令的作用,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對象。
new Function()的三個(gè)步驟:
1.創(chuàng)建類的實(shí)例。將一個(gè)空對象的__proto__指向構(gòu)造函數(shù)的prototype屬性,這個(gè)對象就是要返回的實(shí)例對象。
2.初始化實(shí)例。將參數(shù)傳入構(gòu)造函數(shù)并執(zhí)行構(gòu)造函數(shù),因?yàn)闃?gòu)造函數(shù)內(nèi)部的this指向的是由構(gòu)造函數(shù)生成的實(shí)例。針對this的操作都會(huì)發(fā)生在這個(gè)空對象上,所以通過this,實(shí)例可繼承構(gòu)造函數(shù)的屬性和方法。
3.返回實(shí)例。
構(gòu)造函數(shù)之所以叫“構(gòu)造函數(shù)”,就是因?yàn)闃?gòu)造函數(shù)操作一個(gè)空對象(即this指向的實(shí)例對象),將其“構(gòu)造”為需要的樣子。
普通函數(shù)用new調(diào)用時(shí),因?yàn)槠胀ê瘮?shù)內(nèi)部沒有this,所以使用new命令執(zhí)行后返回的是一個(gè)空對象。new運(yùn)算符接受一個(gè)函數(shù)及其參數(shù)作為構(gòu)造器,根據(jù)傳入?yún)?shù)來創(chuàng)建相同類型但值不同的實(shí)例對象。new命令的作用,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對象。
new Function()的三個(gè)步驟:
1.創(chuàng)建類的實(shí)例。將一個(gè)空對象的__proto__指向構(gòu)造函數(shù)的prototype屬性,這個(gè)對象就是要返回的實(shí)例對象。
2.初始化實(shí)例。將參數(shù)傳入構(gòu)造函數(shù)并執(zhí)行構(gòu)造函數(shù),因?yàn)闃?gòu)造函數(shù)內(nèi)部的this指向的是由構(gòu)造函數(shù)生成的實(shí)例。針對this的操作都會(huì)發(fā)生在這個(gè)空對象上,所以通過this,實(shí)例可繼承構(gòu)造函數(shù)的屬性和方法。
3.返回實(shí)例。
構(gòu)造函數(shù)之所以叫“構(gòu)造函數(shù)”,就是因?yàn)闃?gòu)造函數(shù)操作一個(gè)空對象(即this指向的實(shí)例對象),將其“構(gòu)造”為需要的樣子。普通函數(shù)用new調(diào)用時(shí),因?yàn)槠胀ê瘮?shù)內(nèi)部沒有this,所以使用new命令執(zhí)行后返回的是一個(gè)空對象。
this總是返回一個(gè)對象,簡單說,就是返回屬性或方法“當(dāng)前”所在的對象。隨著函數(shù)使用場景的不同,this的值會(huì)發(fā)生變化可近似理解成this指向的是函數(shù)當(dāng)前的運(yùn)行環(huán)境。但是有一個(gè)總的原則,this指向的是,調(diào)用函數(shù)的那個(gè)對象。
函數(shù)調(diào)用時(shí)的this
函數(shù)直接調(diào)用時(shí)是在全局作用域下調(diào)用的,瀏覽器中的全局作用域是window,this指向window
function fn1(){ console.log(this); //指向window } fn1();
嵌套函數(shù)調(diào)用時(shí)的this
函數(shù)嵌套產(chǎn)生的內(nèi)部函數(shù)的this不指向其父函數(shù),仍然是指向全局變量。
function fn0(){ function fn(){ console.log(this); //這里的this在調(diào)用fn0時(shí)依然指向全局window } fn(); } fn0();
setTimeout、setInterval中的this
延時(shí)函數(shù)執(zhí)行時(shí)是在全局作用域下執(zhí)行,所以this依然指向window
構(gòu)造函數(shù)調(diào)用時(shí)內(nèi)部的this
調(diào)用構(gòu)造函數(shù)時(shí),構(gòu)造函數(shù)內(nèi)的this指向的是構(gòu)造函數(shù)創(chuàng)建的實(shí)例對象。
對象的方法中的this
函數(shù)可以作為一個(gè)對象的屬性,此時(shí)該函數(shù)被稱為該對象的方法。當(dāng)函數(shù)作為一個(gè)對象的方法調(diào)用時(shí),這個(gè)函數(shù)內(nèi)部的this指向調(diào)用該函數(shù)的對象。
var obj1 = { name: "Byron", fn : function(){ console.log(this); } }; obj1.fn(); //調(diào)用后this指向obj1
嵌套對象調(diào)用時(shí)this指向最近那一層的對象,嵌套函數(shù)調(diào)用時(shí)this指向window而不指向最近那層函數(shù)
var a = { p: "Hello", b: { m: function() { console.log(this.p); } } }; a.b.m() // undefined
DOM對象事件綁定,事件處理函數(shù)的this
在事件處理程序中this代表事件源DOM對象。低版本IE的bug會(huì)指向window
document.addEventListener("click", function(e){ console.log(this); //指向DOM對象 var _document = this; setTimeout(function(){ console.log(this); //指向window console.log(_document); }, 200); }, false);原型鏈
“原型鏈”的作用是,讀取對象的某個(gè)屬性時(shí),JavaScript 引擎先尋找對象本身的屬性(同名屬性會(huì)優(yōu)先讀取自身屬性),如果找不到,就通過__proto__到它的原型去找,如果還是找不到,就通過原型的__proto__到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回null。
__proto__屬性是瀏覽器的內(nèi)部屬性,應(yīng)盡量避免使用,建議使用
Object.getPrototype(obj)來獲取對象的原型對象
Object.setPrototypeOf(obj1,obj2)修改對象的原型對象。
獲取一個(gè)對象的原型對象有三種方法:
obj.__proto__ 不靠普,ES6規(guī)范僅瀏覽器部署,其他環(huán)境沒有部署
obj.constructor.prototype 不靠普,obj.constructor.prototype手動(dòng)改變后如果不修正constructor會(huì)導(dǎo)致obj.constructor.prototype指向不準(zhǔn)確
Object.getPrototypeOf(obj) 推薦使用
原型鏈的特性
【1】任何對象上都有__proto__這個(gè)屬性,指向創(chuàng)建該對象的構(gòu)造函數(shù)的prototype屬性(原型對象)。
【2】用面向?qū)ο箝_發(fā)時(shí),把要生成的實(shí)例對象的特有屬性放到構(gòu)造函數(shù)內(nèi),把共有的方法放到構(gòu)造函數(shù)的prototype里面。只要修改構(gòu)造函數(shù)的原型對象prototype,所有構(gòu)造函數(shù)生成的實(shí)例對象上繼承來自原型對象prototype的方法或者屬性都會(huì)改變。
【3】原型鏈:任何對象都是由一個(gè)更高級(jí)的構(gòu)造函數(shù)創(chuàng)建來的。比如對象是由object函數(shù)創(chuàng)建來。prototype是函數(shù)的屬性,__proto__隱式原型是對象(object)的屬性。由于JS中函數(shù)也是對象,所以函數(shù)上也有__proto__屬性。對象的__proto__指向這個(gè)對象的構(gòu)造函數(shù)的prototype
【4】任何函數(shù)都有prototype屬性即原型對象,原型對象默認(rèn)有constructor屬性,指向原型對象prototype所在的構(gòu)造函數(shù),即表示這個(gè)原型對象屬于哪個(gè)構(gòu)造函數(shù)(類型,js無類型的概念)。constructor屬性定義在prototype對象上面,可以被所有實(shí)例對象繼承。修改原型對象時(shí),一般要同時(shí)校正constructor屬性的指向,建議用給原型對象添加方法的形式修改原型對象,而不是完全覆蓋原型對象。
C.prototype.method1 = function (...) { ... };
instanceof
instanceof 判斷一個(gè)對象(不能判斷原始類型值)是不是某個(gè)構(gòu)造函數(shù)(類)的實(shí)例,返回布爾值,通過檢查原型鏈來實(shí)現(xiàn)判斷。instanceof對整個(gè)原型鏈上的對象都有效,因此同一個(gè)實(shí)例對象,可能會(huì)對多個(gè)構(gòu)造函數(shù)都返回true。
var d = new Date(); d instanceof Date // true d instanceof Object // true //instanceof可以用來判斷值的類型 var x = [1, 2, 3]; var y = {}; x instanceof Array // true y instanceof Object // true原型圖示例
function People (name){ this.name = name; this.sayName = function(){ console.log("my name is:" + this.name); } } People.prototype.walk = function(){ console.log(this.name + " is walking"); } var p1 = new People("饑人谷"); var p2 = new People("前端");
圖片轉(zhuǎn)載自知乎
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108098.html
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實(shí)體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街校瑢ο髣t是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣鳌1疚膶⒒貧w面向?qū)ο蟊疽猓瑥膶φZ言感悟的角度闡述為什...
摘要:用代碼可以這樣描述安全到達(dá)國外面向過程既然說了面向?qū)ο螅敲磁c之對應(yīng)的就是面向過程。小結(jié)在這篇文章中,介紹了什么是面向?qū)ο蠛兔嫦蜻^程,以及中對象的含義。 這是 javascript 面向?qū)ο蟀鎵K的第一篇文章,主要講解對面向?qū)ο笏枷氲囊粋€(gè)理解。先說說什么是對象,其實(shí)這個(gè)還真的不好說。我們可以把自己當(dāng)成一個(gè)對象,或者過年的時(shí)候相親,找對象,那么你未來的老婆也是一個(gè)對象。我們就要一些屬性,比...
摘要:之前,本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因?yàn)樗鼘τ诜庋b繼承多態(tài)這些面向?qū)ο笳Z言的特點(diǎn)并沒有在語言層面上提供原生的支持。所以在中出現(xiàn)了等關(guān)鍵字,解決了面向?qū)ο笾谐霈F(xiàn)了問題。 ES6之前,javascript本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因?yàn)樗鼘τ诜庋b、繼承、多態(tài)這些面向?qū)ο笳Z言的特點(diǎn)并沒有在語言層面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以讓我們以...
閱讀 3222·2021-11-23 09:51
閱讀 3566·2021-11-09 09:46
閱讀 3673·2021-11-09 09:45
閱讀 2948·2019-08-29 17:31
閱讀 1866·2019-08-26 13:39
閱讀 2726·2019-08-26 12:12
閱讀 3624·2019-08-26 12:08
閱讀 2243·2019-08-26 11:31