this關(guān)鍵字

  • 記住须板,對(duì)于function函數(shù),this就是call的第一個(gè)參數(shù)>ぢ选!绪颖!
  • 箭頭函數(shù)的this定義:箭頭函數(shù)的this是在定義函數(shù)時(shí)綁定的秽荤,而不是在執(zhí)行過(guò)程中綁定的L鹧佟!窃款!
    人話:箭頭函數(shù)沒(méi)有this课兄,箭頭函數(shù)里出現(xiàn)this的話,你就把它當(dāng)做普通變量晨继,看外面有沒(méi)有定義烟阐,注意啦!所以也可以說(shuō)紊扬,如果箭頭函數(shù)里出現(xiàn)了this蜒茄,那么這個(gè)this的值就是聲明箭頭函數(shù)時(shí)定義的this的值,且后面一直會(huì)是這個(gè)值餐屎,不會(huì)改變L锤稹!腹缩!
  • 普通函數(shù)的this定義:基于函數(shù)的執(zhí)行環(huán)境綁定的S炝!藏鹊!
    人話:誰(shuí)調(diào)用我誰(shuí)就是我的this润讥;

一、分析下面的代碼

第一個(gè)
var a = {
  name: "里面的name",
  sayName: function () {
    console.log("this.name = " + this.name);
  },
};
var name = "外面的name";
function sayName() {
  var sss = a.sayName;
  sss(); //this.name = ?
  a.sayName(); //this.name = ?
  (a.sayName)(); //this.name = ?
  (b = a.sayName)(); //this.name = ?
}
sayName();

1盘寡、首先遇到調(diào)用象对,一定先變成call()的形式!Q绺А勒魔!

  • sayName() >> sayName.call(null)this為window菇曲;
  • sss() >> sss.call(null)冠绢,this為window;
  • a.sayName() >> a.sayName.call(a)常潮,this為對(duì)象a弟胀,如果是對(duì)象后面接一個(gè)函數(shù),那么call的第一個(gè)參數(shù)就是這個(gè)對(duì)象喊式;
  • (a.sayName)() >> a.sayName.call(a)孵户,this為對(duì)象a,注意啦2砹簟夏哭!在js中,你加不加括號(hào)都是一樣的O琢J洹何址!
  • (b = a.sayName)() >> b.call(null)this為window进胯,這個(gè)就相當(dāng)于上面那個(gè)sss用爪,先給b賦值,再調(diào)用b胁镐;
第二個(gè)
var length = 10;
function fn() {
  console.log(this.length);
}
var obj = {
  length: 5,
  method: function (fn) {
    fn();
    arguments[0]();
  },
};
obj.method(fn, 1);

2偎血、還是需要先改寫(xiě)成call()的形式!6⑵颇玷!

  • obj.method(fn, 1) >> obj.method.call(obj,fn, 1)this是對(duì)象obj宠能,arguments是參數(shù)組成的數(shù)組[fn, 1]亚隙;
  • 再往里看method函數(shù),fn() >> fn.call(null)违崇,this為window阿弃;所以第一個(gè)打印出10;
  • arguments[0]() >> arguments.0.call(arguments)羞延,thisarguments人柿,arguments的長(zhǎng)度為2挟憔,所以打印出2;

二、定時(shí)器中的this

1狰右、 如果沒(méi)有特殊指向恃轩,setInterval和setTimeout的回調(diào)函數(shù)中this的指向都是window篙程。這是因?yàn)镴S的定時(shí)器方法是定義在window下的藏畅。
2、看下面的代碼巩步,因?yàn)閮蓚€(gè)setTimeout都是在window下調(diào)用的旁赊,所以它們回調(diào)函數(shù)里面的this都是window,第一個(gè)setTimeout里的回調(diào)函數(shù)是add函數(shù)椅野,它里面的this指向window终畅,所以改動(dòng)的就不是fn里的num,第二個(gè)setTimeout打印fn.num時(shí)竟闪,那肯定還是1啦~~~

function Fn (){
  console.log(this, 'this111')
  this.num = 1
  this.add = function (){
    console.log(this, 'this222')
    this.num++ 
  }
}
const fn = new Fn()
setTimeout(fn.add,1000)
setTimeout(function(){
  console.log(this, 'this333')
  console.log(fn.num, 'num')
},2000)
image.png

3离福、改一下上面第一個(gè)setTimeout里的回調(diào)函數(shù),把里面的this指向fn了

function Fn (){
  console.log(this, 'this111')
  this.num = 1
  this.add = function (){
    console.log(this, 'this222')
    this.num++ 
  }
}
const fn = new Fn()
setTimeout(fn.add.bind(fn),1000)
setTimeout(function(){
  console.log(this, 'this333')
  console.log(fn.num, 'num')
},2000)
image.png

4炼蛤、再看一組

  • 這就需要了解箭頭函數(shù)的this指向和普通函數(shù)的this指向妖爷;
  • 箭頭函數(shù)的this定義:箭頭函數(shù)的this是在定義函數(shù)時(shí)綁定的,而不是在執(zhí)行過(guò)程中綁定的>ㄅ取T獭子寓!
    人話:箭頭函數(shù)沒(méi)有this暗挑,箭頭函數(shù)里出現(xiàn)this的話笋除,你就把它當(dāng)做普通變量,看外面有沒(méi)有定義炸裆,注意啦垃它!所以也可以說(shuō),如果箭頭函數(shù)里出現(xiàn)了this烹看,那么這個(gè)this的值就是聲明箭頭函數(shù)時(shí)定義的this的值国拇,且后面一直會(huì)是這個(gè)值,不會(huì)改變9呤狻=戳摺!
  • 普通函數(shù)的this定義:基于函數(shù)的執(zhí)行環(huán)境綁定的M了肌N袢取!
    人話:誰(shuí)調(diào)用我誰(shuí)就是我的this己儒;
  • 所以下面第一組代碼中的setTimeout(fn.y, 1000)崎岂,雖然setTimeout的this是window,但是fn.y是箭頭函數(shù)闪湾,它的this只需要看它定義時(shí)綁定的對(duì)象冲甘,那就是Fn函數(shù);
function Fn(){
  this.x = function(){
    console.log(this, 'thisxxx')
  }
  this.y = ()=>{
    console.log(this, 'thisyyy')
  }
}
const fn = new Fn()

fn.x()
fn.y()

setTimeout(fn.x, 1000)
setTimeout(fn.y, 1000)
image.png
var obj = {
  x: function(){
    console.log(this, 'thisxxx')
  },
  y: ()=>{
    console.log(this, 'thisyyy')
  }
}

obj.x()
obj.y()
setTimeout(obj.x, 1000)
setTimeout(obj.y, 1000)
image.png

三途样、綁定this的方法

this的動(dòng)態(tài)切換江醇,固然為 JavaScript 創(chuàng)造了巨大的靈活性,但也使得編程變得困難和模糊何暇。有時(shí)陶夜,需要把this固定下來(lái),避免出現(xiàn)意想不到的情況赖晶。JavaScript 提供了call律适、apply、bind這三個(gè)方法遏插,來(lái)切換/固定this的指向捂贿。

  1. Function.prototype.call()
  • call方法的參數(shù),應(yīng)該是一個(gè)對(duì)象胳嘲。第一個(gè)參數(shù)是this厂僧,如果第一個(gè)參數(shù)為空、null和undefined了牛,則默認(rèn)傳入全局對(duì)象颜屠。
var n = 123;
var obj = { n: 456 };
function a() {
  console.log(this.n);
}
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456
  1. Function.prototype.bind()
  • bind方法用于將函數(shù)體內(nèi)的this綁定到某個(gè)對(duì)象辰妙,然后返回一個(gè)綁定了這個(gè)對(duì)象的新函數(shù)。
var d = new Date();
d.getTime() // 1481869925657

var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.

上面代碼中甫窟,我們將d.getTime方法賦給變量print密浑,然后調(diào)用print就報(bào)錯(cuò)了。這是因?yàn)間etTime方法內(nèi)部的this粗井,綁定Date對(duì)象的實(shí)例尔破,賦給變量print以后,內(nèi)部的this已經(jīng)不指向Date對(duì)象的實(shí)例了浇衬。
bind方法可以解決這個(gè)問(wèn)題;

var print = d.getTime.bind(d);
print() // 1481869925657

四懒构、參考下面三篇文章

1、this的值到底是什么耘擂?https://zhuanlan.zhihu.com/p/23804247
2胆剧、如何確定this;https://zhuanlan.zhihu.com/p/25991271
3醉冤、JS里為什么要有this秩霍;https://zhuanlan.zhihu.com/p/30164164

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冤灾,隨后出現(xiàn)的幾起案子前域,更是在濱河造成了極大的恐慌,老刑警劉巖韵吨,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匿垄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡归粉,警方通過(guò)查閱死者的電腦和手機(jī)椿疗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)糠悼,“玉大人届榄,你說(shuō)我怎么就攤上這事【笪梗” “怎么了铝条?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)席噩。 經(jīng)常有香客問(wèn)我班缰,道長(zhǎng),這世上最難降的妖魔是什么悼枢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任埠忘,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘莹妒。我一直安慰自己名船,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布旨怠。 她就那樣靜靜地躺著渠驼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪运吓。 梳的紋絲不亂的頭發(fā)上渴邦,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天疯趟,我揣著相機(jī)與錄音拘哨,去河邊找鬼。 笑死信峻,一個(gè)胖子當(dāng)著我的面吹牛倦青,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盹舞,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼产镐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了踢步?” 一聲冷哼從身側(cè)響起癣亚,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎获印,沒(méi)想到半個(gè)月后述雾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兼丰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年玻孟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳍征。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡黍翎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艳丛,到底是詐尸還是另有隱情匣掸,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布氮双,位于F島的核電站碰酝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏眶蕉。R本人自食惡果不足惜砰粹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碱璃,春花似錦弄痹、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至爽航,卻和暖如春蚓让,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讥珍。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工历极, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人衷佃。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓趟卸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親氏义。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锄列,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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