前? 言
學過程序語言的都知道,我們的程序語言進化是從“面向機器”、到“面向過程”、再到“面向對象”一步步的發展而來。類似于匯編語言這樣的面向機器的語言,隨著時代的發展已經逐漸淘汰;而面向過程的語言也只有C語言老大哥依然堅挺;現在主流的語言(例如Java、C++、PHP等)都是面向對象的語言。 而我們的JavaScript語言,恰恰介于面向過程與面向對象之間,我們稱它為“基于對象”的語言。但是,JS中的OOP依然是我們學習JS的重要一環,當然像“繼承”“封裝”這樣的面向對象特征,都是由模擬實現的。今天,我們就一起來探討一下JS中的面向對象吧!
本章內容將詳細介紹Android事件的具體處理及常見事件。
一、面向對象概述
1.1面向過程與面向對象
面向過程:專注于如何去解決一個問題的過程。編程特點是用一個個函數去實現過程操作,沒有類與對象的概念;
[舉個栗子]
當你想吃一個雞蛋灌餅的時候,面向過程的思維需要你掌握購買食材、和面、烙餅、煎蛋等一系列的方法,然后按照順序一個一個方法的去執行。
面向對象:專注于有哪一個對象實體去解決這個問題。編程特點是:出現了一個個的類,由類去生成對象。
[舉個栗子]
還是想吃雞蛋灌餅,按照面向對象的思維,你需要去找一個買雞蛋灌餅的阿姨,讓他給你做一個。這時候,這個阿姨就是我們解決這個問題的對象。
1.2面向對象三大特征
繼承、封裝、多態
1.3類&對象的關系
① 類:一群有相同特征(屬性)和行為(方法)的集合。
eg: 人類 ?屬性:身高、體重、年齡 ??方法:吃飯、說話、敲代碼
② 對象:從類中,拿出的具有確定屬性值和方法的個體;
eg: 張三 ?屬性:身高180體重180方法:說話--我叫張三
③ 類和對象的關系:
類是抽象的,對象是具體的。(類是對象的抽象化,對象是類的具體化)
通俗的來講:類是一個抽象的概念,表示具有相同屬性和行為的集合,但是類僅僅表明這類群體具有相同的屬性,但是沒有具體的屬性值。而對象是對類的屬性進行具體賦值后,而得到的一個具體的個體;
[舉個栗子]
人類有身高、體重、年齡,但是不能說人類的身高是多少。
而張三,是人類的一個具體個體,身高、體重都有具體值,那么張三就是人類的一個對象
二、JavaScript中的面向對象
2.1創建類和對象的步驟
① 創建一個類(構造函數)。 類名,必須要每個單詞的首字母都大寫
funtion 類名(屬性一){this.屬性=屬性一;this.方法=function(){}//this指向誰? -- 即將調用當前構造函數的對象。}
② 通過類,實例化出一個新的對象;
varobj =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+"生");
}
}//從類中,實例化出一個對象。并給對象的屬性賦值varzhangsan =newPerson("張三",18,"男");//zhangsan.say();varlisi =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指向這個對象
//狹義對象varobj ={
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出的對象
varobj =newfunc();//this--->new出的新obj//【解釋】這個就是第二部分我們使用構造函數new對象的語句,將函數用new關鍵字調用,則函數中的this指向新new出的對象。
3.3綜合小練習
沒學得會,練習來校對!上述的五大準則你理解了嗎?讓我們來做幾個小練習吧?看看這些this都是指向誰?
varobj1 ={
name:'obj1',
arr:[setTimeout(func,3000),1,2,3]
}
document.getElementById("div").onclick = obj1.arr[0];//函數最終調用者:setTimeout ,符合規律⑤ this--->windowvarobj2 ={
name:'obj1',
arr:[func,1,2,3]
}
document.getElementById("div").onclick = obj2.arr[0]();//函數最終調用者:數組下標 ,符合規律③ this--->arrvarobj3 ={
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模擬面試題
小練習都做出來了嗎?不要驕傲哦~~來看一套模擬面試題吧!!下面的打印語句都應該是什么結果呢?先不要看答案,自己做一下吧~
varfullname = 'John Doe';varobj ={
fullname:'Colin Ihrig',
prop: {
fullname:'Aurelio De Rosa',
getFullname:function() {returnthis.fullname;
}
}
};vararr = [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的面向對象。