javascript中的call版保,apply呜笑,bind

我們經(jīng)常會碰到這樣一些問題:

  • 代碼1
var Person={
    name: "bob",
    getName: function(){
        console.log(this.name);
    }
}
var getMyName = Person.getName;
getMyname(); //undefined

或者是這樣的問題:

  • 代碼2
function Person(name){
 this.nickname = name;
 this.distractedGreeting = function() {
 
   setTimeout(function(){
     console.log("Hello, my name is " + this.nickname);
   }, 500);
 }
}
var alice = new Person('Alice');
alice.distractedGreeting();
//Hello, my name is undefined

在JavaScript中,this的指向是在運(yùn)行函數(shù)時確定的彻犁,而不是定義函數(shù)時確定的叫胁。第一段代碼,因?yàn)?code>getMyName是在全局環(huán)境下運(yùn)行的袖裕,故this指向的上下文為window曹抬。

第二段代碼,setTimeout的運(yùn)行環(huán)境同樣為全局急鳄,故this指向的也是window,返回值為undefined谤民。
JavaScript新手經(jīng)常犯的一個錯誤,是將一個方法從對象中拿出來,然后再調(diào)用疾宏,希望方法中的this是原來的對象张足。(比如在回調(diào)中傳入這個方法。)如果不做特殊處理的話坎藐,一般會丟失原來的對象为牍。

callapply就是用來解決這個問題的。

call

我們首先來看call的用法岩馍。以代碼1為例:

var Person={
    name: "bob",
    getName: function(){
        console.log(this.name);
    }
}
var getMyName = Person.getName;
getMyName.call(Person); //bob

通過call方法碉咆,我們成功地讓getMyName方法輸出了bob。call方法的作用蛀恩,簡單來說疫铜,就是改變執(zhí)行函數(shù)的this指向。它可以讓執(zhí)行函數(shù)的執(zhí)行環(huán)境指向call第一個參數(shù)的環(huán)境下双谆。

call方法可以有多個參數(shù)壳咕。第一個參數(shù)以外的參數(shù),是傳給執(zhí)行函數(shù)的傳參顽馋。以代碼1為例:

var Person={
    name: "bob",
    getName: function(a,b){
        console.log(this.name+' '+a+' '+b);
    }
}
var getMyName = Person.getName;
getMyName.call(Person,2,'abc'); //bob 2 abc

apply

apply方法與call非常相似谓厘。同樣是改變執(zhí)行函數(shù)的this指向apply方法和call方法在使用方法上幾乎沒有什么區(qū)別寸谜。
代碼1為例:

var Person={
    name: "bob",
    getName: function(){
        console.log(this.name);
    }
}
var getMyName = Person.getName;
getMyName.apply(Person); //bob

在執(zhí)行函數(shù)沒有傳參時竟稳,從代碼上看,我們幾乎看不出差別,僅僅是把call換成了apply住练。

他們之間唯一的不同地啰,就是apply只有兩個參數(shù)愁拭,第二個參數(shù)必須是一個數(shù)組讲逛,執(zhí)行函數(shù)的傳參,以數(shù)組的形式傳遞岭埠。而call的傳參盏混,必須一個一個傳入。
代碼1為例:

var Person={
    name: "bob",
    getName: function(a,b){
        console.log(this.name+' '+a+' '+b);
    }
}
var getMyName = Person.getName;
getMyName.apply(Person,[2,'abc']); //bob 2 abc

需要注意的是惜论,如果callapply的第一個參數(shù)寫的是null许赃,那么this指向的是window對象。
代碼1為例:

var Person={
    name: "bob",
    getName: function(){
        console.log(this.name);
    }
}
var getMyName = Person.getName;
getMyName.apply(null); //Window

bind

最后我們來說說bind馆类。

bind方法會創(chuàng)建一個新函數(shù),稱為綁定函數(shù)混聊。當(dāng)調(diào)用這個綁定函數(shù)時,綁定函數(shù)會以創(chuàng)建它時傳入bind方法的第一個參數(shù)作為 this,傳入bind 方法的第二個以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。

代碼2以前的解決辦法乾巧,通常是緩存this句喜。

function Person(name){
  this.nickname = name;
  this.distractedGreeting = function() {
    var self = this; // <-- 注意這一行!
    setTimeout(function(){
      console.log("Hello, my name is " + self.nickname); // <-- 還有這一行!
    }, 500);
  }
}
 
var alice = new Person('Alice');
alice.distractedGreeting();
// after 500ms logs "Hello, my name is Alice"

而我們使用bind方法,能更簡單明了地解決這個問題沟于。

function Person(name){
  this.nickname = name;
  this.distractedGreeting = function() {
    setTimeout(function(){
      console.log("Hello, my name is " + this.nickname);
    }.bind(this), 500); // <-- this line!
  }
}
 
var alice = new Person('Alice');
alice.distractedGreeting();
// after 500ms logs "Hello, my name is Alice"

代碼1的問題同樣可以用bind方法來解決咳胃。

var Person={
    name: "bob",
    getName: function(){
        console.log(this.name);
    }
}
var getMyName = Person.getName;
var bindGetName = getMyName.bind(Person);
getMyName();//bob

這里我們需要注意的是,bindcallapply的不同之處旷太,就是bind返回的是一個修改過后的函數(shù)展懈。

剛才提到了,bind方法同樣可以有多個參數(shù)供璧。
代碼1為例:

var Person={
    name: "bob",
    getName: function(a,b,c,d){
        console.log(this.name+' '+a+' '+b+' '+c+' '+d);
    }
}
var getMyName = Person.getName;
var bindGetName = getMyName.bind(Person,12,34);
bindGetName('ab','cd');//bob 12 34 ab cd

可以看到存崖,傳入bind 方法的第二個以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。

最后睡毒,我們來總結(jié)一下(敲黑板来惧,這里是你們要的重點(diǎn)!B类帧)

  • 用途:都是在特定的作用域中調(diào)用函數(shù)违寞,實(shí)際上等于設(shè)置函數(shù)體內(nèi)this對象的值。
  • apply接受兩個參數(shù):一個是在其中運(yùn)行函數(shù)的作用域偶房,另一個是參數(shù)數(shù)組趁曼。參數(shù)數(shù)組可以是arguments對象。
  • callapply的區(qū)別僅在于接受參數(shù)的方式不同棕洋。call的參數(shù)必須逐個列舉出來挡闰。
  • 重要用途能夠擴(kuò)充函數(shù)賴以運(yùn)行的作用域。 對象與方法間不需要有任何耦合關(guān)系
  • bind方法會創(chuàng)建一個函數(shù)的實(shí)例摄悯,其this值會被綁定到傳給bind函數(shù)的值赞季。
  • 傳入bind 方法的第二個以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奢驯,一起剝皮案震驚了整個濱河市申钩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘪阁,老刑警劉巖撒遣,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異管跺,居然都是意外死亡义黎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門豁跑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廉涕,“玉大人,你說我怎么就攤上這事艇拍『桑” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵淑倾,是天一觀的道長馏鹤。 經(jīng)常有香客問我,道長娇哆,這世上最難降的妖魔是什么湃累? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮碍讨,結(jié)果婚禮上治力,老公的妹妹穿的比我還像新娘。我一直安慰自己勃黍,他們只是感情好宵统,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著覆获,像睡著了一般马澈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弄息,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天痊班,我揣著相機(jī)與錄音,去河邊找鬼摹量。 笑死涤伐,一個胖子當(dāng)著我的面吹牛馒胆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凝果,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼祝迂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了器净?” 一聲冷哼從身側(cè)響起型雳,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掌动,沒想到半個月后四啰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粗恢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了欧瘪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眷射。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佛掖,靈堂內(nèi)的尸體忽然破棺而出妖碉,到底是詐尸還是另有隱情,我是刑警寧澤芥被,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布欧宜,位于F島的核電站,受9級特大地震影響拴魄,放射性物質(zhì)發(fā)生泄漏冗茸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一匹中、第九天 我趴在偏房一處隱蔽的房頂上張望夏漱。 院中可真熱鬧,春花似錦顶捷、人聲如沸挂绰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葵蒂。三九已至,卻和暖如春重虑,著一層夾襖步出監(jiān)牢的瞬間践付,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工嚎尤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荔仁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像乏梁,于是被迫代替她去往敵國和親次洼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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