JavaScript面向對象(一)——JS OOP基礎與JS 中This指向詳解

前  言

  學過程序語言的都知道,我們的程序語言進化是從“面向機器”、到“面向過程”、再到“面向對象”一步步的發展而來。類似於彙編語言這樣的面向機器的語言,隨着時代的發展已經逐漸淘汰;而面向過程的語言也只有C語言老大哥依然堅挺;現在主流的語言(例如Java、C++、PHP等)都是面向對象的語言。 而我們的JavaScript語言,恰恰介於面向過程與面向對象之間,我們稱它爲“基於對象”的語言。但是,JS中的OOP依然是我們學習JS的重要一環,當然像“繼承”“封裝”這樣的面向對象特徵,都是由模擬實現的。今天,我們就一起來探討一下JS中的面向對象吧!

 

一、面向對象概述

1.1面向過程與面向對象

  面向過程:專注於如何去解決一個問題的過程。編程特點是用一個個函數去實現過程操作,沒有類與對象的概念;

  [舉個栗子]

  當你想吃一個雞蛋灌餅的時候,面向過程的思維需要你掌握購買食材、和麪、烙餅、煎蛋等一系列的方法,然後按照順序一個一個方法的去執行。

 

  面向對象:專注於有哪一個對象實體去解決這個問題。編程特點是:出現了一個個的類,由類去生成對象。

  [舉個栗子]

  還是想吃雞蛋灌餅,按照面向對象的思維,你需要去找一個買雞蛋灌餅的阿姨,讓他給你做一個。這時候,這個阿姨就是我們解決這個問題的對象。

 

1.2面向對象三大特徵

  繼承、封裝、多態

 

1.3類&對象的關係

  ① 類:一羣有相同特徵(屬性)和行爲(方法)的集合。

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

  ② 對象:從類中,拿出的具有確定屬性值和方法的個體;

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

  ③ 類和對象的關係:

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

 

  通俗的來講:類是一個抽象的概念,表示具有相同屬性和行爲的集合,但是類僅僅表明這類羣體具有相同的屬性,但是沒有具體的屬性值。而對象是對類的屬性進行具體賦值後,而得到的一個具體的個體;

  [舉個栗子]

  人類有身高、體重、年齡,但是不能說人類的身高是多少。而張三,是人類的一個具體個體,身高、體重都有具體值,那麼張三就是人類的一個對象

 

二、JavaScript中的面向對象

2.1創建類和對象的步驟

  ① 創建一個類(構造函數)。 類名,必須要每個單詞的首字母都大寫

funtion 類名(屬性一){
  this.屬性=屬性一;
  this.方法=function(){}//this指向誰? -- 即將調用當前構造函數的對象。
}

  ② 通過類,實例化出一個新的對象;

var obj =new類名(屬性一的Value);//原構造函數中this,指向新創建的obj對象;
obj.方法(); 調用方法
obj.屬性; 調用屬性

 

2.2內創建類和對象代碼示例

//① 定義一個類(構造函數)

functionPerson(name,age,sex){

  //類的屬性

  this.name =name;

  this.age =age;

  this.sex =sex;

  //類的方法

  this.say =function(){

    alert("我叫"+this.name+";今年"+this.age+"歲;是一個"+this.sex+"生");

  }

}

//從類中,實例化出一個對象。並給對象的屬性賦值

var zhangsan =newPerson("張三",18,"男");//

zhangsan.say();

var lisi =newPerson("李二狗",16,"男");//

lisi.say();

 

三、JavaScript中的this指向問題

  在上一部分中,我們創建了一個類,並通過這個類new出了一個對象。 但是,這裏面出現了大量的this。 很多同學就要懵逼了,this不是“這個”的意思嗎?爲什麼我在函數裏面寫的this定義的屬性,最後到了函數new出的對象呢??

  今天,就讓我們撥開迷霧,牢牢記住“傑小瑞this五大準則”。幫你縷清關於JS中this指向的一切謎團。

3.1誰最終調用函數,this指向誰

  首先來明白this指向的基本概念,“this永遠指向函數的最終調用者”,理解這句話,我們先明確三個基本要素:

  ①this指向的,永遠只可能是對象!!!!!!

  ②this指向誰,永遠不取決於this寫在哪!!而是取決於函數在哪調用。

  ③this指向的對象,我們稱之爲函數的上下文context,也叫函數的調用者

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

  那麼,接下來,就讓我們祭出“傑小瑞this五大法寶”吧!記住這5條,所有this指向手到擒來!

 

3.2※※※this指向的規律(傑小瑞this五大準則)

  首先,我們寫這樣的一個函數:

functionfunc(){

  console.log(this);

}

  Question:請問this指向誰?

  如果面試有人這麼問你!你可以直接甩他一個大嘴巴!然後大聲告訴他“this指向誰,取決於誰調用函數!而不取決於函數寫在哪裏!只有函數聲明,沒有函數調用語句。我不知道this指向誰!”

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

 

  哈哈,開完玩笑,我們來研究一下,下面那個函數中的this,到底有可能指向誰?傑小瑞老師總結了5大準則,一起來看看吧~~

  ①通過函數名()直接調用:this指向window

func();//this--->window
//【解釋】 我們直接用一個函數名()調用,函數裏面的this,永遠指向window。

  ② 通過對象.函數名()調用的:this指向這個對象

//狹義對象

var obj ={

  name:"obj",

  func1 :func

};

obj.func1();//this--->obj

//【解釋】我們將func函數名,當做了obj這個對象的一個方法,然後使用對象名.方法名, 這時候函數裏面的this指向這個obj對象。



//廣義對象

document.getElementById("div").onclick =function(){

  this.style.backgroundColor = "red";

};//this--->div

//【解釋】對象打點調用還有一個情況,我們使用getElementById取到一個div控件,也是一種廣義的對象,用它打點調用函數,則函數中的this指向這個div對象。

  ③ 函數作爲數組的一個元素,通過數組下標調用的:this指向這個數組

vararr = [func,1,2,3];

arr[0]();//this--->arr

//【解釋】這個,我們把函數名,當做數組中的一個元素。使用數組下標調用,則函數中的this將指向這個數組arr。

  ④ 函數作爲window內置函數的回調函數調用:this指向window

setTimeout(func,1000);//this--->window
//setInterval(func,1000);
//【解釋】使用setTimeout、setInterval等window內置函數調用函數,則函數中的this指向window。

  ⑤ 函數作爲構造函數,用new關鍵字調用時:this指向新new出的對象

var obj =newfunc();//this--->new出的新obj

//【解釋】這個就是第二部分我們使用構造函數new對象的語句,將函數用new關鍵字調用,則函數中的this指向新new出的對象。

3.3綜合小練習

沒學得會,練習來校對!上述的五大準則你理解了嗎?讓我們來做幾個小練習吧?看看這些this都是指向誰?

var obj1 ={

  name:'obj1',

  arr:[setTimeout(func,3000),1,2,3]

}

document.getElementById("div").onclick = obj1.arr[0]; //函數最終調用者:setTimeout ,符合規律⑤ this--->window

var obj2 ={

  name:'obj1',

  arr:[func,1,2,3]

}

document.getElementById("div").onclick = obj2.arr[0]();//函數最終調用者:數組下標 ,符合規律③ this--->arr

var obj3 ={

  name:'obj1',

  arr:[{name:'arrObj',fun:func},1,2,3]

}

document.getElementById("div").onclick = obj3.arr[0].fun();//函數最終調用者:{name:'arrObj',fun:func} ,符合規律② this--->obj

 

3.4模擬面試題

小練習都做出來了嗎?不要驕傲哦~~來看一套模擬面試題吧!!下面的打印語句都應該是什麼結果呢?先不要看答案,自己做一下吧~

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指向數組,數組沒有fullname屬性,所以未定義!

console.log(obj.prop.getFullname());//Aurelio De Rosa//函數最終調用者:obj.prop  this--->obj.propvartest =obj.prop.getFullname;

console.log(test());//John Doe//函數最終調用者: 函數() window  this-->windowobj.func =obj.prop.getFullname;

console.log(obj.func());//this最終調用者是obj,所以this指向obj

 

好了,通過本篇博客,我們瞭解了什麼是面向對象、類和對象的關係、JS中聲明類與對象的步驟,以及重點講解的this指向問題! 希望能夠幫助大家真正的理解了this的認知,接下來的博客讓我們繼續探討JavaScript的面向對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章