概 述
學(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)利。