[轉載]JavaScript的this

注意:誰調用它男杈,this就指向誰

全局執(zhí)行

  • 瀏覽器
console.log(this);
// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}

打印出來了window對象。

  • Node
console.log(this);
// global
  • 總結:在全局作用域中它的 this 執(zhí)行當前的全局對象(瀏覽器端是 Window旺垒,node 中是 global)肤无。

函數(shù)執(zhí)行

  • 純粹的函數(shù)調用
    最普通的函數(shù)使用方法:
function test() {
  console.log(this);
};
test();
// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}

我們可以看到,一個函數(shù)被直接調用的時候竞漾,屬于全局調用业岁,這時候它的 this 指向 全局對象;

  • 嚴格模式: 'use strict'
    如果在嚴格模式的情況下執(zhí)行純粹的函數(shù)調用棍好,那么這里的的 this 并不會指向全局借笙,而是 undefined业稼,這樣的做法是為了消除 js 中一些不嚴謹?shù)男袨椋?/li>
use strict';
function test() {
  console.log(this);
};
test();
// undefined

當然念链,把它放在一個立即執(zhí)行函數(shù)中會更好,避免了污染全局:

(function (){
  "use strict";
 console.log(this);
})();
// undefined

作為對象的方法調用

當一個函數(shù)被當作一個對象的方法調用的時候:

var obj = {
  name: 'qiutc',
  foo: function() {
    console.log(this.name);
  }
}
obj.foo();
// 'qiutc'

這時候谦纱,this 指向當前的這個對象跨嘉;
如果把對象的方法賦值給一個變量祠乃,然后直接調用這個變量呢:

var obj = {
  name: 'qiutc',
  foo: function() {
    console.log(this);
  }
}
var test = obj.foo;
test();
// Window

可以看到兑燥,這時候 this 執(zhí)行了全局,當我們把 test = obj.foo 嘱支,text直接把等號右邊當做一個函數(shù)挣饥,并不管什么obj扔枫。test 直接指向了一個函數(shù)的引用短荐,這時候叹哭,其實和 obj 這個對象沒有關系了话速,所以泊交,它是被當作一個普通函數(shù)來直接調用廓俭,因此,this 指向全局對象。重點淋硝。

經(jīng)典例子

var obj = {
  name: 'qiutc',
  foo: function() {
    console.log(this); //直接打印出obj整個對象
  },
  foo2: function() {
    console.log(this); //打印出整個obj對象
    var _this = this;
    setTimeout(function() {
      console.log(this);  // Window
      console.log(_this);  // Object {name: "qiutc"}
    }, 1000);
  }
}
obj.foo2();
obj.foo();
  • 首先竿报,因為誰調用this烈菌,this就指向誰,所以花履,foo和foo2里面的console.log(this)直接指向調用他們的obj對象诡壁,打印出Obj整個對象妹卿。
  • 然后纽帖,在看setTimeout里面的懊直。在外面雕崩,var _this = this; 這個this是指向obj的(上面已經(jīng)打印出來了)融撞。用一個變量 _this 來儲存尝偎。所以console.log(_this);可以打印出obj對象致扯。因為我們已經(jīng)用_this來指向obj對象了抖僵,所以console.log(this); // Window耍群。this只能指向全局了蹈垢。
  • 還有一點就是在foo2作用域內非setTimeout作用域內console.log(this);發(fā)現(xiàn)打印出obj對象曹抬。console.log(_this);也是這樣。說明setTimeout塊級作用域隔絕了foo2作用域的滲透。

作為一個構造函數(shù)使用

在 js 中赖临,為了實現(xiàn)類兢榨,我們需要定義一些構造函數(shù)吵聪,在調用一個構造函數(shù)的時候需要加上 new 這個關鍵字:

function Person(name) {
  this.name = name;
  console.log(this);
}
var p = new Person('qiutc');
// Person {name: "qiutc"}

我們可以看到當作構造函數(shù)調用時吟逝,this 指向了這個構造函數(shù)調用時候實例化出來的對象块攒;

當然佃乘,構造函數(shù)其實也是一個函數(shù)趣避,如果我們把它當作一個普通函數(shù)執(zhí)行程帕,這個 this 仍然執(zhí)行全局:

function Person(name) {
  this.name = name;
  console.log(this);
}
var p = Person('qiutc');
// Window

其區(qū)別在于骆捧,如何調用函數(shù)(new

箭頭函數(shù)

在 ES6 的新規(guī)范中敛苇,加入了箭頭函數(shù)顺呕,它和普通函數(shù)最不一樣的一點就是 this 的指向了株茶。用閉包來解決 this 的指向問題,用上了箭頭函數(shù)就可以更完美的解決。

var obj = {
  name: 'qiutc',
  foo: function() {
    console.log(this);
  },
  foo2: function() {
    console.log(this);
    setTimeout(() => {
      console.log(this);  // Object {name: "qiutc"}
    }, 1000);
  }
}
obj.foo2();

可以看到卧抗,在 setTimeout 執(zhí)行的函數(shù)中社裆,本應該打印出在 Window泳秀,但是在這里 this 卻指向了 obj嗜傅,原因就在于檩赢,給 setTimeout 傳入的函數(shù)(參數(shù))是一個箭頭函數(shù):

箭頭函數(shù)體內的this對象,就是定義時所在的對象憔狞,而不是使用時所在的對象瘾敢。

根據(jù)例子我們理解一下這句話:
obj.foo2() 執(zhí)行的時候簇抵,當前的 this 指向 obj;在執(zhí)行 setTimeout 時候晃财,我們先是定義了一個匿名的箭頭函數(shù),關鍵點就在這愉舔,箭頭函數(shù)內的 this 執(zhí)行定義時所在的對象轩缤,就是指向定義這個箭頭函數(shù)時作用域內的 this火的,也就是 obj.foo2 中的 this馏鹤,即 obj假瞬;所以在執(zhí)行箭頭函數(shù)的時候脱茉,它的 this -> obj.foo2 中的 this -> obj琴许;

簡單來說, 箭頭函數(shù)中的 this 只和定義它時候的作用域的 this 有關益兄,而與在哪里以及如何調用它無關净捅,同時它的 this 指向是不可改變的荆永。這個箭頭函數(shù)在foo2的作用域下具钥,所以就指向foo2液兽。

所以對于箭頭函數(shù)四啰,只要看它在哪里創(chuàng)建的就行拟逮。

轉載于

JavaScript 中的 this

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末恋追,一起剝皮案震驚了整個濱河市罚屋,隨后出現(xiàn)的幾起案子脾猛,更是在濱河造成了極大的恐慌猛拴,老刑警劉巖愉昆,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跛溉,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機嚎尤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進店門诺苹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來收奔,“玉大人,你說我怎么就攤上這事翩肌〗疲” “怎么了粱坤?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長濒旦。 經(jīng)常有香客問我尔邓,道長梯嗽,這世上最難降的妖魔是什么慷荔? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上偿警,老公的妹妹穿的比我還像新娘螟蒸。我一直安慰自己七嫌,他們只是感情好诵原,可當我...
    茶點故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布绍赛。 她就那樣靜靜地躺著吗蚌,像睡著了一般蚯妇。 火紅的嫁衣襯著肌膚如雪侮措。 梳的紋絲不亂的頭發(fā)上分扎,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天畏吓,我揣著相機與錄音菲饼,去河邊找鬼宏悦。 笑死镐确,一個胖子當著我的面吹牛诗越,可吹牛的內容都是我干的嚷狞。 我是一名探鬼主播荣堰,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼薇搁,長吁一口氣:“原來是場噩夢啊……” “哼屡拨!你這毒婦竟也來了呀狼?” 一聲冷哼從身側響起哥艇,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤貌踏,失蹤者是張志新(化名)和其女友劉穎窟勃,沒想到半個月后秉氧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汁咏,經(jīng)...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡攘滩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年漂问,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,989評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩驱,死狀恐怖冬竟,靈堂內的尸體忽然破棺而出泵殴,到底是詐尸還是另有隱情笑诅,我是刑警寧澤吆你,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布妇多,位于F島的核電站者祖,受9級特大地震影響七问,放射性物質發(fā)生泄漏械巡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一芦鳍、第九天 我趴在偏房一處隱蔽的房頂上張望柠衅。 院中可真熱鬧籍琳,春花似錦、人聲如沸势誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谈喳。三九已至婿禽,卻和暖如春扭倾,著一層夾襖步出監(jiān)牢的瞬間吆录,已是汗流浹背琼牧。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工撬槽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留趾撵,地道東北人占调。 一個月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓究珊,卻偏偏與公主長得像言津,于是被迫代替她去往敵國和親焕刮。 傳聞我的和親對象是個殘疾皇子碰镜,可洞房花燭夜當晚...
    茶點故事閱讀 45,995評論 2 361

推薦閱讀更多精彩內容

  • 葡萄藤PPT JS中this的指向 大家好磅叛,我是IT修真院鄭州分院第6期的學員王棟宪躯,一枚正直乔宿、純潔详瑞、善良的前端程序...
    17064閱讀 628評論 0 2
  • 1.概念 在JavaScript中,this 是指當前函數(shù)中正在執(zhí)行的上下文環(huán)境计寇,因為這門語言擁有四種不同的函數(shù)調...
    BluesCurry閱讀 1,135評論 0 2
  • 前言 本文為學習過程中的this小節(jié)番宁,作為一名JavaScript自學未成才的編程人員赖阻,還沒從“原型繼承”中回過神...
    01_Jack閱讀 743評論 0 3
  • 在面向對象的語言中(例如Java,C#等)棋电,this含義是明確且具體的苇侵,即指向當前對象榆浓。一般在編譯期綁定。而在ja...
    一木_qintb閱讀 400評論 0 0
  • 函數(shù)和對象 1沉眶、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念谎倔。通過函數(shù)可以封裝任意多條語句片习,而且...
    道無虛閱讀 4,586評論 0 5