老生常談JavaScript面向?qū)ο蠡A(chǔ)與this指向問題
前 言
我們的程序語言經(jīng)歷了從“面向機(jī)器”、到“面向過程”、再到“面向?qū)ο蟆钡囊粋€(gè)過程。而JavaScript是一門基于對象的一門語言,它介于面向過程與面向?qū)ο笾g。在學(xué)習(xí)JavaScript的過程中,OOP是非常重要的一環(huán),下面我們來一起探討一下JS中的面向?qū)ο蟀桑。。?/p>
1 、OOP的基礎(chǔ)問題
1.1什么是面向過程和面向?qū)ο螅?/strong>
面向過程:專注于如何去解決一個(gè)問題的過程步驟。編程特點(diǎn)是由一個(gè)個(gè)的函數(shù)去實(shí)現(xiàn)每一步的過程步驟,沒有類和對象的概念。
面向?qū)ο螅簩W⒂谟赡囊粋€(gè)對象來解決這個(gè)問題。編程特點(diǎn)是出現(xiàn)了一個(gè)個(gè)的類,從類中拿到這個(gè)對象,由這個(gè)對象去解決具體的問題。
對于調(diào)用者來說,面向過程需要調(diào)用者自己去實(shí)現(xiàn)各種函數(shù)。而面向?qū)ο?,只需要告訴調(diào)用者對象中具體方法的功能,而不需要調(diào)用者了解方法中的實(shí)現(xiàn)細(xì)節(jié)。
1.2面向?qū)ο蟮娜筇卣?/strong>
繼承、封裝、多態(tài)
1.3類和對象的關(guān)系
① 類:一類具有相同特征(屬性)和行為(方法)的集合。
比如:人類-->屬性:身高、體重、性別 方法:吃飯、說話、走路
② 對象:從類中,拿出具有確定屬性值和方法的個(gè)體。
比如:張三-->屬性:身高180、體重180 方法:說話-->我叫張三,身高180
③ 類和對象的關(guān)系
類是抽象的,對象是具體的(類是對象的抽象化,對象是類的具體化)
解釋一下:
類是一個(gè)抽象的概念,只能說類有屬性和方法,但是不能給屬性賦具體的值。比如說人類有姓名,但是不能說人類的姓名叫啥。。。
對象是一個(gè)具體的個(gè)例,是將類中的屬性進(jìn)行具體賦值而來的個(gè)體。比如說張三是人類的一個(gè)個(gè)體,可以說張三的姓名叫張三。也就是張三對人類的每一個(gè)屬性進(jìn)行了具體的賦值,那么張三就是由人類產(chǎn)生的一個(gè)對象。
2、 JavaScript中的面向?qū)ο?/strong>
2.1創(chuàng)建類和對象的步驟
①創(chuàng)建一個(gè)類(構(gòu)造函數(shù)):類名必須使用大駝峰法則,即每個(gè)單詞的首字母必須大寫。
function 類名(屬性1){ this.屬性1 = 屬性1; this.方法 = function(){ //方法中要調(diào)用自身屬性,必須要使用this.屬性 } }
②通過類,實(shí)例化(new)出一個(gè)對象。
var obj = new 類名(屬性1的具體值);
obj.屬性; 調(diào)用屬性
obj.方法(); 調(diào)用方法
③注意事項(xiàng)
>>>通過類名,new出一個(gè)對象的過程,叫做“類的實(shí)例化”
>>>類中的this,會在實(shí)例化的時(shí)候,指向新new出的對象。所以,this.屬性 this.方法,實(shí)際上是將屬性和方法綁定在即將new出的對象上面。
>>>在類中,要調(diào)用自身屬性,必須使用this.屬性名、如果直接使用變量名,則無法訪問對應(yīng)的屬性。
>>>類名必須使用大駝峰法則,注意與普通函數(shù)的區(qū)別。
2.2兩個(gè)重要屬性constructor和instanceof
①constructor:返回當(dāng)前對象的構(gòu)造函數(shù)
>>>zhangsan.constructor = Person; √
②instanceof:檢測一個(gè)對象,是不是一個(gè)類的實(shí)例;
>>>lisi instanceof Person √ lisi是通過Person類new出的
>>>lisi instanceof Object √ 所有對象都是Object的實(shí)例
>>>Person instanceof Object √ 函數(shù)本身也是對象
3、 JavaScript中的this指向問題
在上一部分中,我們創(chuàng)建了一個(gè)類,并通過這個(gè)類new出了一個(gè)對象。 但是,這里面出現(xiàn)了大量的this。 很多同學(xué)就要懵逼了,this不是“這個(gè)”的意思嗎?為什么我在函數(shù)里面寫的this定義的屬性,最后到了函數(shù)new出的對象呢??
3.1誰最終調(diào)用函數(shù),this就指向誰!
① this指向誰,不應(yīng)該考慮函數(shù)在哪聲明,而應(yīng)該考慮函數(shù)在哪調(diào)用??!
② this指向的,永遠(yuǎn)只可能是對象,不可能是函數(shù)?。?/p>
③ this指向的對象,叫做函數(shù)的上下文context,也叫函數(shù)的調(diào)用者。
3.2this指向的規(guī)律(與函數(shù)的調(diào)用方式息息相關(guān)!)
① 通過函數(shù)名()調(diào)用的,this永遠(yuǎn)指向window
func(); // this--->window //【解釋】 我們直接用一個(gè)函數(shù)名()調(diào)用,函數(shù)里面的this,永遠(yuǎn)指向window。
② 通過對象.方法調(diào)用的,this指向這個(gè)對象
// 狹義對象 var obj = { name:"obj", func1 :func }; obj.func1(); // this--->obj //【解釋】我們將func函數(shù)名,當(dāng)做了obj這個(gè)對象的一個(gè)方法,然后使用對象名.方法名, 這時(shí)候函數(shù)里面的this指向這個(gè)obj對象。 // 廣義對象 document.getElementById("div").onclick = function(){ this.style.backgroundColor = "red"; }; // this--->div //【解釋】對象打點(diǎn)調(diào)用還有一個(gè)情況,我們使用getElementById取到一個(gè)div控件,也是一種廣義的對象,用它打點(diǎn)調(diào)用函數(shù),則函數(shù)中的this指向這個(gè)div對象。
③ 函數(shù)作為數(shù)組的一個(gè)元素,用數(shù)組下標(biāo)調(diào)用,this指向這個(gè)數(shù)組
var arr = [func,1,2,3]; arr[0](); // this--->arr //【解釋】這個(gè),我們把函數(shù)名,當(dāng)做數(shù)組中的一個(gè)元素。使用數(shù)組下標(biāo)調(diào)用,則函數(shù)中的this將指向這個(gè)數(shù)組arr。
④ 函數(shù)作為window內(nèi)置函數(shù)的回調(diào)函數(shù)使用,this指向window。比如setTimeout、setInterval等
setTimeout(func,1000);// this--->window //setInterval(func,1000); //【解釋】使用setTimeout、setInterval等window內(nèi)置函數(shù)調(diào)用函數(shù),則函數(shù)中的this指向window。
⑤ 函數(shù)作為構(gòu)造函數(shù),使用new關(guān)鍵字調(diào)用,this指向新new出的對象
var obj = new func(); //this--->new出的新obj //【解釋】這個(gè)就是第二部分我們使用構(gòu)造函數(shù)new對象的語句,將函數(shù)用new關(guān)鍵字調(diào)用,則函數(shù)中的this指向新new出的對象。
3.3關(guān)于this問題的面試題
var fullname = 'John Doe'; var obj = { fullname: 'Colin Ihrig', prop: { fullname: 'Aurelio De Rosa', getFullname: function() { return this.fullname; } } }; console.log(obj.prop.getFullname()); // 函數(shù)的最終調(diào)用者 obj.prop var test = obj.prop.getFullname; console.log(test()); // 函數(shù)的最終調(diào)用者 test() this-> window obj.func = obj.prop.getFullname; console.log(obj.func()); // 函數(shù)最終調(diào)用者是obj var arr = [obj.prop.getFullname,1,2]; arr.fullname = "JiangHao"; console.log(arr[0]()); // 函數(shù)最終調(diào)用者數(shù)組
好了,這篇博客,我們了解了什么是面向?qū)ο?、類和對象的關(guān)系、JS中聲明類與對象的步驟,以及重點(diǎn)講解的this指向問題! 希望能夠幫助大家真正的理解了this的認(rèn)知,下面我會繼續(xù)給大家分享關(guān)于面向?qū)ο蠓矫娴膯栴}。多謝大家的支持?。。?/p>
以上這篇老生常談JavaScript面向?qū)ο蠡A(chǔ)與this指向問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- js綁定事件this指向發(fā)生改變的問題解決方法
- JavaScript call apply使用 JavaScript對象的方法綁定到DOM事件后this指向問題
- 我所理解的JavaScript中的this指向
- JavaScript this在函數(shù)中的指向及實(shí)例詳解
- 淺談JS中幾種輕松處理''this''指向方式
- js中的this的指向問題詳解
- 詳解JavaScript中關(guān)于this指向的4種情況
- js中this的指向問題歸納總結(jié)
- 用最簡單的方法判斷JavaScript中this的指向(推薦)
- 關(guān)于JavaScript中的this指向問題總結(jié)篇
- JS中this的4種綁定規(guī)則詳解
- 詳解JavaScript的this指向和綁定
相關(guān)文章
layer.open關(guān)閉父窗口 以及調(diào)用父頁面的方法
今天小編就為大家分享一篇layer.open關(guān)閉父窗口 以及調(diào)用父頁面的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08Bootstrap編寫一個(gè)同時(shí)適用于PC、平板、手機(jī)的登陸頁面
這篇文章主要為大家詳細(xì)介紹了Bootstrap編寫一個(gè)同時(shí)適用于PC、平板、手機(jī)的登陸頁面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06微信小程序?qū)崿F(xiàn)音頻文件播放進(jìn)度的實(shí)例代碼
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)音頻文件播放進(jìn)度的實(shí)例代碼,代碼包括對進(jìn)度條的實(shí)現(xiàn)及進(jìn)度條的滑動(dòng),對大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03簡單實(shí)現(xiàn)Bootstrap標(biāo)簽頁
這篇文章主要教大家簡單實(shí)現(xiàn)Bootstrap標(biāo)簽頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12借助script進(jìn)行Http跨域請求:JSONP實(shí)現(xiàn)原理及代碼
script元素的src屬性能設(shè)置URL并發(fā)起HTTP GET請求實(shí)現(xiàn)腳本操作HTTP可以跨域通信而不受限與同源策略,接下來為大家詳細(xì)介紹下Http跨域請求實(shí)現(xiàn),感興趣的你可以參考下哈2013-03-03利用transition實(shí)現(xiàn)文字上下抖動(dòng)的效果
這篇文章主要給大家介紹了利用transition屬性如何實(shí)現(xiàn)文字上下抖動(dòng)的效果,文中給出了詳細(xì)的介紹和完整的實(shí)例代碼,相信對大家的學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面來一起看看吧。2017-01-01在瀏覽器中獲取當(dāng)前執(zhí)行的腳本文件名的代碼
同事提了一個(gè)問題,如何在瀏覽器中動(dòng)態(tài)插入的 JavaScript 文件中,獲取當(dāng)前文件名?2011-07-07