[常用技巧]setTimeout/setInterval綁定參數(shù)和修正this

p.s 此文只說setTimeout涌韩。setInterval請如法炮制 肮帐。另,由于本人是新手哼丈,如有錯誤之處還望斧正启妹。

setTimeout的第一個參數(shù)接受一個函數(shù)定義式。

function put(p1,p2){
  console.log('put',p1,p2);
}

綁定函數(shù)和傳入?yún)?shù)

setTimeout第一個參數(shù)傳入一個函數(shù)定義式醉旦,第二個參數(shù)傳入延遲時間饶米。至于函數(shù)定義式參數(shù)的傳入方式(準確說是給函數(shù)的參數(shù)們設(shè)置默認值桨啃。并返回這個帶參數(shù)默認值的函數(shù)定義式。)

1.直接使用函數(shù)名檬输,不帶()照瘾,此時表示直接傳入一個定義式。

setTimeout(put,1000);

缺點:不能給put定義式傳參數(shù)

2.外部再包含一個function

setTimeout(function(){
  put('some','value');
},1000)

缺點:可讀性不高
優(yōu)點:但最容易理解

3.使用bind傳入?yún)?shù)

setTimeout(put.bind(this,p1,p2),1000);

bind的返回結(jié)果依然是一個函數(shù)定義式丧慈。但能傳入指定的this析命,并傳入指定的參數(shù)。

4.setTimeout余下參數(shù)

setTimeout(put,1000,p1,p2)

就很簡單逃默,在延遲參數(shù)后面繼續(xù)跟參數(shù)就行了鹃愤,全會被算到put函數(shù)上。不過低版本IE似乎不支持

this的問題

setTimeout默認的內(nèi)部this就是window完域,你在一個別的對象里寫個setTimeout直接用this會翻車昼浦。有如下修正方式

var someObj = {
  name:'tmh',
  intro:'一切為了老玩家',
  getIntro:function(){
      console.log(this.intro);
  },
  DelayPutIntro:function(){
      setTimeout(/**一個this綁定指向正確的函數(shù)定義式**/,1000);
  }
}

1.暴力指向,var self = this;

someObj.DelayPutIntro = function(){
    var self = this; // setTimeout外部獲取this筒主,保存在self中
    setTimeout(function(){
      console.log(self.intro);
  },1000)
}
someObj.DelayPutIntro();

2.bind綁定this

someObj.DelayPutIntro = function(){
  setTimeout(someObj.getIntro.bind(this,p1,...,pn),1000);
}
someObj.DelayPutIntro();

上文提到過bind可以設(shè)置函數(shù)的參數(shù)默認值关噪,同時也可以改變this指向。第一個參數(shù)用于控制this乌妙,后續(xù)參數(shù)用于綁定默認參數(shù)使兔。

在程序尚未真正執(zhí)行前,此處Bind中出現(xiàn)的this指代的是該function作用域內(nèi)的this藤韵,即somObj虐沥。效果等同于setTimeout(someObj.getIntro.bind(someObj,p1,...,pn),1000)

注:由于bind第一個參數(shù)正確指向了this。所以也能寫成這種形式setTimeout(this.getIntro.bind(this,p1,...,pn),1000);

3.()=>{}箭頭函數(shù)

someObj.DelayPutIntro = function(){
  setTimeout(
  ()=>{console.log(this.intro)},1000);
}
someObj.DelayPutIntro();

或者

someObj.DelayPutIntro = function(){
  setTimeout(
  ()=>{this.getIntro()},1000);
}
someObj.DelayPutIntro();

箭頭函數(shù)語法看ES6泽艘,除了表達更簡便外欲险,還能自動綁定this為定義時而不是使用時。范圍同bind匹涮。

進一步天试,this的范圍

this指向當前作用域的宿主。所以我們使用Bind或者箭頭函數(shù)時然低,作用域是someObj.DelayPutIntro這個函數(shù)喜每,其宿主為someObj。
為了證實this指向當前作用域的宿主是可靠的雳攘。有如下例子:

var someObj = {
  name: 'tmh',
  intro: '一切為了老玩家',
  getIntro: function () {
    console.log(this.intro);
  }
}

someObj.DelayPutIntro = function () {

  var inner = {
    name: '小tmh',
    intro: '老玩家算個屁',
    getIntro: function () {
      console.log(this.intro);
    },
    DelayPutIntro: function () {
      setTimeout(this.getIntro.bind(this), 1000);
    }
  }
  inner.DelayPutIntro();
}
someObj.DelayPutIntro();

注意觀察我們在someObj.DelayPutIntro函數(shù)中再創(chuàng)建了一個Inner對象带兜。那么這段代碼中setTimeout里函數(shù)定義式綁定的this應(yīng)該指向什么?

是的吨灭,該this的作用域是inner.DelayPutIntro這個函數(shù)刚照,故而this指向其宿主Inner,打印的結(jié)果也是inner的intro而不是someObj的intro了。

關(guān)于js對象喧兄,作用域无畔,作用域鏈還有this指向的問題還有很多啊楚。此處不鋪開闡述了。


總結(jié)一下

函數(shù)綁定及參數(shù)綁定

  1. 直接填寫函數(shù)名傳入不帶參的定義式
  2. 外套一個function/或者()=>{}箭頭函數(shù)檩互,內(nèi)部寫一個傳入了參的函數(shù)引用特幔。
  3. xx.bind(this,...porps)返回一個xx改造后的新函數(shù)咨演,該函數(shù)經(jīng)由bind綁定了新的參數(shù)默認值
  4. setTimeout(put,1000,p1,p2,...,pn)闸昨,直接在setTimeout的規(guī)定參數(shù)后面跟新參數(shù),將綁到put上

this

  1. bind綁定
  2. 箭頭函數(shù)綁定
  3. var self = this;暴力指向
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末薄风,一起剝皮案震驚了整個濱河市饵较,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌遭赂,老刑警劉巖循诉,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撇他,居然都是意外死亡茄猫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門困肩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來划纽,“玉大人,你說我怎么就攤上這事锌畸∮铝樱” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵潭枣,是天一觀的道長比默。 經(jīng)常有香客問我,道長盆犁,這世上最難降的妖魔是什么命咐? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮谐岁,結(jié)果婚禮上侈百,老公的妹妹穿的比我還像新娘。我一直安慰自己翰铡,他們只是感情好钝域,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锭魔,像睡著了一般例证。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上迷捧,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天织咧,我揣著相機與錄音胀葱,去河邊找鬼。 笑死笙蒙,一個胖子當著我的面吹牛抵屿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捅位,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼轧葛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了艇搀?” 一聲冷哼從身側(cè)響起尿扯,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎焰雕,沒想到半個月后衷笋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡矩屁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年辟宗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吝秕。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡泊脐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郭膛,到底是詐尸還是另有隱情晨抡,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布则剃,位于F島的核電站耘柱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏棍现。R本人自食惡果不足惜调煎,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望己肮。 院中可真熱鬧士袄,春花似錦、人聲如沸谎僻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艘绍。三九已至赤拒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挎挖。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工这敬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕉朵。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓崔涂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親始衅。 傳聞我的和親對象是個殘疾皇子冷蚂,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

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