JavaScript的this和作用域

本文主要討論一下JS的作用域和this關(guān)鍵字春贸。作用域求类,就是你的方法或者變量可訪問的區(qū)域狱杰,是他們執(zhí)行的上下文。如果你見過這樣的代碼:

function someFunc() {
  var _this = this;
  something.on("click", function() {
    console.log(_this);
  });
};

你就會很好奇為什么要用this賦值給一個變量_this呢期奔?你看完這篇文章就會清楚這個問題的答案了侧馅。

第一種作用域叫做全局作用域(Global Scope)這很容易定義,如果一個方法呐萌、變量是全局作用域的馁痴,那么它就可以從任何的地方訪問到。在瀏覽器里肺孤,全局作用域就是window對象罗晕。所以,如果你的代碼里有:

var x = 9;

你其實(shí)是在給window.x賦值為9(在瀏覽器里運(yùn)行的時候)渠旁。如果你喜歡的話攀例,也可以寫成window.x = 9,當(dāng)然這不是很必要顾腊。全局作用域?qū)ο蟮膶傩钥梢栽诖a的任何地方訪問到粤铭。

另外的作用域就只有局部作用域了。在JavaScript里一般就是一個方法內(nèi)部的作用域杂靶。比如:

function someFunction() {
  var x = 5;
}
console.log(x); // undefined

變量x是在方法內(nèi)部初始化的梆惯,那么就只能在方法內(nèi)部訪問。

一些需要注意的地方

如果你聲明了一個變量吗垮,而且在聲明的時候忘記使用var關(guān)鍵字垛吗。那么,這個變量自動被置為全局變量烁登。比如:

function someFunction(){
  x = 5;
}

// 執(zhí)行一個這個方法怯屉,完成x的全局設(shè)置
someFunction();

console.log(x); // 5

這是一個非常差的實(shí)踐。你應(yīng)該盡量少的往全局作用域添加屬性。這也是為什么你會經(jīng)诚锹纾看到一些庫赌躺,比如jQuery會這么干:

(function() {
  var jQuery = {/*全部的方法都在這里*/};
  window.jQuery = jQuery;
})();

把全有的屬性、方法都放在一個方法里羡儿。然后立刻執(zhí)行這個方法就會把全部的屬性和方法都綁定在了局部作用域里礼患。最后把jQuery對象綁定到全局作用域,間接的把之前定義的屬性和方法都暴露出來方便調(diào)用掠归。顯然我大量的減少了jQuery的代碼缅叠,但是這就是jQuery代碼如何工作的。

由于局部作用域只有通過方法的定義來實(shí)現(xiàn)虏冻。任何在一個方法內(nèi)部定義的方法都可以訪問外部方法里定義的變量肤粱。比如:

function outer() {
  var x = 5;
  function inner() {
    console.log(x); // 5
  }

  inner();
}

但是outer()方法不可以訪問inner()方法定義的任何變量。

function outer() {
  var x = 5;
  function inner() {
    console.log(x); // 5
    var y = 100;
  }

  inner();
  console.log(y); // undefined
}

這很容易理解兄旬。但是當(dāng)我們試圖要探究this關(guān)鍵字的時候就又變得復(fù)雜了狼犯。我相信很多人都遇到過這樣的問題:

${'myLink'}.on('click', function() {
  console.log(this);  // 指向myLink

  $.ajax({
    // 設(shè)置ajax相關(guān)
    success: function() {
      console.log(this);  // 指向的是全局對象。 领铐?悯森??
    }
  });
});

this是在方法執(zhí)行的時候自動賦值的變量绪撵。它的值和方法的調(diào)用方式有很大的關(guān)系瓢姻。比如:

function foo() {
  console.log(this);  // global object
}

theApp = {};
theApp.foo = function() {
  console.log(this);  // 指向theApp對象
}

var link = doeument.getElementById('myLink');
link.addEventListener('click', function() {
  console.log(this); // 指向link
});

MDN對第三個例子的解釋非常到位:

事件的this總是指向出發(fā)這個事件的元素對象。比如使用一個通用的事件監(jiān)聽器來處理一系列的有相似事件的元素音诈。當(dāng)使用addEventListener把一個方法添加到一個元素的事件處理器的時候幻碱,這個方法的this值就被改變了。注意细溅,this的值是從調(diào)用者里傳給方法的褥傍。

這么做:$('myLink').on('click', function() {})意味著link被點(diǎn)擊的時候方法就會執(zhí)行。由于這個方法是處理link的事件的喇聊,所以this的值就是這個link元素恍风。

在Ajax請求的success回調(diào)方法只是一個普通的方法。所以誓篱,當(dāng)它被調(diào)用的時候this指向的是全局對象朋贬。任何對象,不是對象方法或者事件的時候會遇到的情況窜骄。

上面的原因也就是你在很多地方看到var _this = this;或者var that = this;的原因锦募。來看一個例子:

$('myLink').on('click', function() {
  console.log(this); //指向myLink
  var _this = this;
  $.ajax({
    // ajax設(shè)置
    success: function() {
      console.log(this);  // 指向全局對象
      console.log(_this); // 指向myLink
    }
  });
});

原文地址:https://javascriptplayground.com/javascript-variable-scope-this/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邻遏,隨后出現(xiàn)的幾起案子糠亩,更是在濱河造成了極大的恐慌虐骑,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件削解,死亡現(xiàn)場離奇詭異富弦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氛驮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來济似,“玉大人矫废,你說我怎么就攤上這事∨榇溃” “怎么了蓖扑?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長台舱。 經(jīng)常有香客問我律杠,道長,這世上最難降的妖魔是什么竞惋? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任柜去,我火速辦了婚禮,結(jié)果婚禮上拆宛,老公的妹妹穿的比我還像新娘嗓奢。我一直安慰自己,他們只是感情好浑厚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布股耽。 她就那樣靜靜地躺著,像睡著了一般钳幅。 火紅的嫁衣襯著肌膚如雪物蝙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天敢艰,我揣著相機(jī)與錄音诬乞,去河邊找鬼。 笑死盖矫,一個胖子當(dāng)著我的面吹牛丽惭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辈双,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼责掏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了湃望?” 一聲冷哼從身側(cè)響起换衬,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤痰驱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瞳浦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體担映,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年叫潦,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝇完。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡矗蕊,死狀恐怖短蜕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情傻咖,我是刑警寧澤朋魔,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站卿操,受9級特大地震影響警检,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜害淤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一扇雕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筝家,春花似錦洼裤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莹菱,卻和暖如春移国,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背道伟。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工迹缀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜜徽。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓祝懂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拘鞋。 傳聞我的和親對象是個殘疾皇子砚蓬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容