JavaScript面向?qū)ο?一)——JS OOP基礎(chǔ)與JS 中This指向詳解

概 述

學(xué)過(guò)程序語(yǔ)言的都知道,我們的程序語(yǔ)言進(jìn)化是從“面向機(jī)器”、到“面向過(guò)程”、再到“面向?qū)ο蟆币徊讲降陌l(fā)展而來(lái)。類似于匯編語(yǔ)言這樣的面向機(jī)器的語(yǔ)言,隨著時(shí)代的發(fā)展已經(jīng)逐漸淘汰;而面向過(guò)程的語(yǔ)言也只有C語(yǔ)言老大哥依然堅(jiān)挺;現(xiàn)在主流的語(yǔ)言(例如Java、C++、PHP等)都是面向?qū)ο蟮恼Z(yǔ)言。 而我們的JavaScript語(yǔ)言,恰恰介于面向過(guò)程與面向?qū)ο笾g,我們稱它為“基于對(duì)象”的語(yǔ)言。但是,JS中的OOP依然是我們學(xué)習(xí)JS的重要一環(huán),當(dāng)然像“繼承”“封裝”這樣的面向?qū)ο筇卣?,都是由模擬實(shí)現(xiàn)的。今天,我們就一起來(lái)探討一下JS中的面向?qū)ο蟀桑?/p>

本章內(nèi)容將詳細(xì)介紹Android事件的具體處理及常見(jiàn)事件。

一、面向?qū)ο蟾攀?/h1>

1.面向過(guò)程與面向?qū)ο?/h3>

面向過(guò)程:專注于如何去解決一個(gè)問(wèn)題的過(guò)程。編程特點(diǎn)是用一個(gè)個(gè)函數(shù)去實(shí)現(xiàn)過(guò)程操作,沒(méi)有類與對(duì)象的概念;

[舉個(gè)栗子]

當(dāng)你想吃一個(gè)雞蛋灌餅的時(shí)候,面向過(guò)程的思維需要你掌握購(gòu)買(mǎi)食材、和面、烙餅、煎蛋等一系列的方法,然后按照順序一個(gè)一個(gè)方法的去執(zhí)行。

面向?qū)ο?/strong>:專注于有哪一個(gè)對(duì)象實(shí)體去解決這個(gè)問(wèn)題。編程特點(diǎn)是:出現(xiàn)了一個(gè)個(gè)的類,由類去生成對(duì)象。

[舉個(gè)栗子]

還是想吃雞蛋灌餅,按照面向?qū)ο蟮乃季S,你需要去找一個(gè)買(mǎi)雞蛋灌餅的阿姨,讓他給你做一個(gè)。 這時(shí)候,這個(gè)阿姨就是我們解決這個(gè)問(wèn)題的對(duì)象。

2.面向?qū)ο笕筇卣?/h3>

繼承、封裝、多態(tài)

3.類&對(duì)象的關(guān)系

:一群有相同特征(屬性)和行為(方法)的集合。

eg: 人類 屬性:身高、體重、年齡 方法:吃飯、說(shuō)話、敲代碼

對(duì)象:從類中,拿出的具有確定屬性值和方法的個(gè)體;

eg: 張三 屬性:身高180 體重180 方法:說(shuō)話--我叫張三

類和對(duì)象的關(guān)系

類是抽象的,對(duì)象是具體的。(類是對(duì)象的抽象化,對(duì)象是類的具體化)

通俗的來(lái)講:類是一個(gè)抽象的概念,表示具有相同屬性和行為的集合,但是類僅僅表明這類群體具有相同的屬性,但是沒(méi)有具體的屬性值。而對(duì)象是對(duì)類的屬性進(jìn)行具體賦值后,而得到的一個(gè)具體的個(gè)體;

[舉個(gè)栗子]

人類有身高、體重、年齡,但是不能說(shuō)人類的身高是多少。

而張三,是人類的一個(gè)具體個(gè)體,身高、體重都有具體值,那么張三就是人類的一個(gè)對(duì)象。

二、JavaScript中的面向?qū)ο?/h1>

1.創(chuàng)建類和對(duì)象的步驟

① 創(chuàng)建一個(gè)類(構(gòu)造函數(shù))。 類名,必須要每個(gè)單詞的首字母都大寫(xiě)

funtion 類名(屬性一){
                  this.屬性=屬性一;
                this.方法=function(){}
                 // this指向誰(shuí)? -- 即將調(diào)用當(dāng)前構(gòu)造函數(shù)的對(duì)象。
         }

② 通過(guò)類,實(shí)例化出一個(gè)新的對(duì)象;

 var obj = new 類名(屬性一的Value);
                 // 原構(gòu)造函數(shù)中this,指向新創(chuàng)建的obj對(duì)象;
         obj.方法(); 調(diào)用方法
         obj.屬性; 調(diào)用屬性

2.內(nèi)創(chuàng)建類和對(duì)象代碼示例

// ① 定義一個(gè)類(構(gòu)造函數(shù))
        function Person(name,age,sex){
            // 類的屬性
            this.name = name;
            this.age = age;
            this.sex = sex;
            
            // 類的方法
            this.say = function(){
                alert("我叫"+this.name+";今年"+this.age+"歲;是一個(gè)"+this.sex+"生");
            }
        }
        
        // 從類中,實(shí)例化出一個(gè)對(duì)象。并給對(duì)象的屬性賦值
        var zhangsan = new Person("張三",18,"男");
        //zhangsan.say();
        
        var lisi = new Person("李二狗",16,"男");
        //lisi.say();

三、JavaScript中的this指向問(wèn)題

在上一部分中,我們創(chuàng)建了一個(gè)類,并通過(guò)這個(gè)類new出了一個(gè)對(duì)象。 但是,這里面出現(xiàn)了大量的this。 很多同學(xué)就要懵逼了,this不是“這個(gè)”的意思嗎?為什么我在函數(shù)里面寫(xiě)的this定義的屬性,最后到了函數(shù)new出的對(duì)象呢??

今天,就讓我們撥開(kāi)迷霧,牢牢記住“杰小瑞this五大準(zhǔn)則”。幫你縷清關(guān)于JS中this指向的一切謎團(tuán)。

1.誰(shuí)最終調(diào)用函數(shù),this指向誰(shuí)

首先來(lái)明白this指向的基本概念,“this永遠(yuǎn)指向函數(shù)的最終調(diào)用者”,理解這句話,我們先明確三個(gè)基本要素:

① this指向的,永遠(yuǎn)只可能是對(duì)象?。。。。。?/strong>

② this指向誰(shuí),永遠(yuǎn)不取決于this寫(xiě)在哪?。《侨Q于函數(shù)在哪調(diào)用。

③ this指向的對(duì)象,我們稱之為函數(shù)的上下文context,也叫函數(shù)的調(diào)用者

可能有同學(xué)要說(shuō)了,我明確了這三個(gè)要素了,我也看不懂this的指向啊。 var obj = new function(); 第二部分的這句話,怎么就讓函數(shù)(類)中的this指向obj了???一臉懵逼ing。。。

那么,接下來(lái),就讓我們祭出“杰小瑞this五大法寶”吧!記住這5條,所有this指向手到擒來(lái)!

3.2※※※this指向的規(guī)律(杰小瑞this五大準(zhǔn)則)

首先,我們寫(xiě)這樣的一個(gè)函數(shù):

function func(){
    console.log(this);
}

Question:請(qǐng)問(wèn)this指向誰(shuí)?

如果面試有人這么問(wèn)你!你可以直接甩他一個(gè)大嘴巴!然后大聲告訴他“this指向誰(shuí),取決于誰(shuí)調(diào)用函數(shù)!而不取決于函數(shù)寫(xiě)在哪里!只有函數(shù)聲明,沒(méi)有函數(shù)調(diào)用語(yǔ)句。我不知道this指向誰(shuí)!

然后,面試官一定會(huì)捂著臉告訴你,“你被錄用了/(ㄒoㄒ)/~~”

哈哈,開(kāi)完玩笑,我們來(lái)研究一下,下面那個(gè)函數(shù)中的this,到底有可能指向誰(shuí)?杰小瑞老師總結(jié)了5大準(zhǔn)則,一起來(lái)看看吧~~

① 通過(guò)函數(shù)名()直接調(diào)用:this指向window

func(); // this--->window
//【解釋】 我們直接用一個(gè)函數(shù)名()調(diào)用,函數(shù)里面的this,永遠(yuǎn)指向window。

② 通過(guò)對(duì)象.函數(shù)名()調(diào)用的:this指向這個(gè)對(duì)象

// 狹義對(duì)象
    var obj = {
        name:"obj",
        func1 :func
    };
    obj.func1(); // this--->obj
//【解釋】我們將func函數(shù)名,當(dāng)做了obj這個(gè)對(duì)象的一個(gè)方法,然后使用對(duì)象名.方法名, 這時(shí)候函數(shù)里面的this指向這個(gè)obj對(duì)象。

    // 廣義對(duì)象
    document.getElementById("div").onclick = function(){
        this.style.backgroundColor = "red";
}; // this--->div
//【解釋】對(duì)象打點(diǎn)調(diào)用還有一個(gè)情況,我們使用getElementById取到一個(gè)div控件,也是一種廣義的對(duì)象,用它打點(diǎn)調(diào)用函數(shù),則函數(shù)中的this指向這個(gè)div對(duì)象。

③ 函數(shù)作為數(shù)組的一個(gè)元素,通過(guò)數(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ù)調(diào)用:this指向window

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)用時(shí):this指向新new出的對(duì)象

var obj = new func(); //this--->new出的新obj
//【解釋】這個(gè)就是第二部分我們使用構(gòu)造函數(shù)new對(duì)象的語(yǔ)句,將函數(shù)用new關(guān)鍵字調(diào)用,則函數(shù)中的this指向新new出的對(duì)象。

3.綜合小練習(xí)

沒(méi)學(xué)得會(huì),練習(xí)來(lái)校對(duì)! 上述的五大準(zhǔn)則你理解了嗎?讓我們來(lái)做幾個(gè)小練習(xí)吧?看看這些this都是指向誰(shuí)?

var obj1 = {
            name:'obj1',
            arr:[setTimeout(func,3000),1,2,3]
        }
        document.getElementById("div").onclick = obj1.arr[0];
        // 函數(shù)最終調(diào)用者:setTimeout ,符合規(guī)律⑤ this--->window
        
        
        var obj2 = {
            name:'obj1',
            arr:[func,1,2,3]
        }
        document.getElementById("div").onclick = obj2.arr[0]();
        // 函數(shù)最終調(diào)用者:數(shù)組下標(biāo) ,符合規(guī)律③ this--->arr
        

        var obj3 = {
            name:'obj1',
            arr:[{name:'arrObj',fun:func},1,2,3]
        }
        document.getElementById("div").onclick = obj3.arr[0].fun();
    // 函數(shù)最終調(diào)用者:{name:'arrObj',fun:func} ,符合規(guī)律② this--->obj

4.模擬面試題

小練習(xí)都做出來(lái)了嗎?不要驕傲哦~
來(lái)看一套模擬面試題吧?。∠旅娴拇蛴≌Z(yǔ)句都應(yīng)該是什么結(jié)果呢?先不要看答案,自己做一下吧~

var fullname = 'John Doe';
        var obj = {
           fullname: 'Colin Ihrig',
           prop: {
              fullname: 'Aurelio De Rosa',
              getFullname: function() {
                 return this.fullname;
              }
           }
        };
        var arr = [obj.prop.getFullname,12,3,4,5];
        console.log(arr[0]());//this指向數(shù)組,數(shù)組沒(méi)有fullname屬性,所以未定義!
        console.log(obj.prop.getFullname()); // Aurelio De Rosa
        //函數(shù)最終調(diào)用者:obj.prop  this--->obj.prop
        var test = obj.prop.getFullname; 
        console.log(test());  // John Doe
        // 函數(shù)最終調(diào)用者: 函數(shù)() window  this-->window
        obj.func = obj.prop.getFullname;
        console.log(obj.func()); // this最終調(diào)用者是obj,所以this指向obj

好了,通過(guò)本篇博客,我們了解了什么是面向?qū)ο?、類和?duì)象的關(guān)系、JS中聲明類與對(duì)象的步驟,以及重點(diǎn)講解的this指向問(wèn)題! 希望能夠幫助大家真正的理解了this的認(rèn)知,接下來(lái)的博客讓我們繼續(xù)探討JavaScript的面向?qū)ο蟆?/p>

作者:杰瑞教育Allen老師
版權(quán)聲明:本文版權(quán)歸煙臺(tái)杰瑞教育科技有限公司和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容