JavaScript中的call厌衙、apply和bind方法

JavaScript中的call(), apply()和bind()是Function.prototype下的方法畦木,都是用于改變函數(shù)運(yùn)行時(shí)上下文兜粘,最終的返回值是你調(diào)用的方法的返回值申窘,若該方法沒有返回值,則返回undefined孔轴。這幾個(gè)方法很好地體現(xiàn)了js函數(shù)式語(yǔ)言特性剃法,在js中幾乎每一次編寫函數(shù)式語(yǔ)言風(fēng)格的代碼,都離不開call和apply路鹰。

1. call()

  • 描述:
    call()方法使用一個(gè)指定的this值和單獨(dú)給出的一個(gè)或多個(gè)參數(shù)來(lái)調(diào)用一個(gè)函數(shù)玄窝。
    call()允許為不同的對(duì)象分配和調(diào)用屬于一個(gè)對(duì)象的函數(shù)/方法。
    call()提供新的 this 值給當(dāng)前調(diào)用的函數(shù)/方法悍引。你可以使用 call 來(lái)實(shí)現(xiàn)繼承:寫一個(gè)方法,然后讓另外一個(gè)新的對(duì)象來(lái)繼承它(而不是在新對(duì)象中再寫一次這個(gè)方法)帽氓。
  • 語(yǔ)法
function.call(thisArg, arg1, arg2, ...)
  • 參數(shù):
    thisArg
    function 函數(shù)運(yùn)行時(shí)指定的 this趣斤。需要注意的是,指定的 this 值并不一定是該函數(shù)執(zhí)行時(shí)真正的 this 值黎休,如果這個(gè)函數(shù)在[非嚴(yán)格模式]下運(yùn)行浓领,則指定為 nullundefinedthis 值會(huì)自動(dòng)指向全局對(duì)象(瀏覽器中就是 window 對(duì)象),同時(shí)值為原始值(數(shù)字势腮,字符串联贩,布爾值)的 this 會(huì)指向該原始值的自動(dòng)包裝對(duì)象。
    arg1, arg2, ...
    指定的參數(shù)列表捎拯。
  • 返回值:
    使用調(diào)用者提供的 this 值和參數(shù)調(diào)用該函數(shù)的返回值泪幌。若該方法沒有返回值,則返回 undefined署照。
  • 示例:
function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);
// expected output: "cheese"

2. apply()

  • 描述
    apply() 方法調(diào)用一個(gè)具有給定this值的函數(shù)祸泪,以及作為一個(gè)數(shù)組(或類似數(shù)組對(duì)象)提供的參數(shù)。
    在調(diào)用一個(gè)存在的函數(shù)時(shí)建芙,你可以為其制定一個(gè)this對(duì)象没隘,this指當(dāng)前對(duì)象,也就是正在調(diào)用這個(gè)函數(shù)的對(duì)象禁荸。使用apply右蒲,你可以只寫一次這個(gè)方法然后在另一個(gè)對(duì)象中繼承它阀湿,而不用在新對(duì)象中重復(fù)寫該方法。
    applycall() 非常相似瑰妄,不同之處在于提供參數(shù)的方式陷嘴。apply 使用參數(shù)數(shù)組而不是一組參數(shù)列表。apply 可以使用數(shù)組字面量(array literal)翰撑,如 fun.apply(this, ['eat', 'bananas'])罩旋,或數(shù)組對(duì)象, 如 fun.apply(this, new Array('eat', 'bananas'))眶诈。
    你也可以使用 arguments對(duì)象作為 argsArray 參數(shù)涨醋。 arguments 是一個(gè)函數(shù)的局部變量。 它可以被用作被調(diào)用對(duì)象的所有未指定的參數(shù)逝撬。 這樣浴骂,你在使用apply函數(shù)的時(shí)候就不需要知道被調(diào)用對(duì)象的所有參數(shù)。 你可以使用arguments來(lái)把所有的參數(shù)傳遞給被調(diào)用對(duì)象宪潮。 被調(diào)用對(duì)象接下來(lái)就負(fù)責(zé)處理這些參數(shù)溯警。
    從 ECMAScript 第5版開始,可以使用任何種類的類數(shù)組對(duì)象狡相,就是說(shuō)只要有一個(gè) length 屬性和(0..length-1)范圍的整數(shù)屬性梯轻。例如現(xiàn)在可以使用 NodeList 或一個(gè)自己定義的類似 {'length': 2, '0': 'eat', '1': 'bananas'} 形式的對(duì)象。

需要注意:Chrome 14 以及 Internet Explorer 9 仍然不接受類數(shù)組對(duì)象尽棕。如果傳入類數(shù)組對(duì)象喳挑,它們會(huì)拋出異常。

  • 語(yǔ)法
function.apply(thisArg, [argsArray])
  • 參數(shù)
    thisArg
    可選的滔悉。在 function 函數(shù)運(yùn)行時(shí)使用的 this 值伊诵。請(qǐng)注意,this可能不是該方法看到的實(shí)際值:如果這個(gè)函數(shù)處于非嚴(yán)格模式下回官,則指定為 nullundefined 時(shí)會(huì)自動(dòng)替換為指向全局對(duì)象曹宴,原始值會(huì)被包裝。
    argsArray
    可選的歉提。一個(gè)數(shù)組或者類數(shù)組對(duì)象笛坦,其中的數(shù)組元素將作為單獨(dú)的參數(shù)傳給function函數(shù)。如果改參數(shù)的值為nullundefined苔巨,則表示不需要傳入任何參數(shù)弯屈。從ECMAScript 5 開始可以使用類數(shù)組對(duì)象。
  • 返回值
    調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果恋拷。
  • 示例
var numbers = [5, 6, 2, 3, 7];

var max = Math.max.apply(null, numbers);

console.log(max);
// expected output: 7

var min = Math.min.apply(null, numbers);

console.log(min);
// expected output: 2

3. bind()

  • 描述
    bind()方法創(chuàng)建一個(gè)新的函數(shù)资厉,在調(diào)用時(shí)設(shè)置this關(guān)鍵字為提供的值。并在調(diào)用新函數(shù)時(shí)蔬顾,將給定參數(shù)列表作為原函數(shù)的參數(shù)序列的前若干項(xiàng)宴偿。
    bind() 函數(shù)會(huì)創(chuàng)建一個(gè)新綁定函數(shù)(bound function湘捎,BF)。綁定函數(shù)是一個(gè)exotic function object(怪異函數(shù)對(duì)象窄刘,ECMAScript 2015中的術(shù)語(yǔ))窥妇,它包裝了原函數(shù)對(duì)象。調(diào)用綁定函數(shù)通常會(huì)導(dǎo)致執(zhí)行包裝函數(shù)娩践。
    綁定函數(shù)具有以下內(nèi)部屬性:
    [[BoundTargetFunction]] - 包裝的函數(shù)對(duì)象
    [[BoundThis]] - 在調(diào)用包裝函數(shù)時(shí)始終作為this值傳遞的值活翩。
    [[BoundArguments]] - 列表,在對(duì)包裝函數(shù)做任何調(diào)用都會(huì)優(yōu)先用列表元素填充參數(shù)列表翻伺。
    [[Call]] - 執(zhí)行與此對(duì)象關(guān)聯(lián)的代碼材泄。通過(guò)函數(shù)調(diào)用表達(dá)式調(diào)用。內(nèi)部方法的參數(shù)是一個(gè)this值和一個(gè)包含通過(guò)調(diào)用表達(dá)式傳遞給函數(shù)的參數(shù)的列表吨岭。
    當(dāng)調(diào)用綁定函數(shù)時(shí)拉宗,它調(diào)用[[BoundTargetFunction]]上的內(nèi)部方法[[Call]],就像這樣Call(boundThis, args)辣辫。其中旦事,boundThis[[BoundThis]]args[[BoundArguments]]加上通過(guò)函數(shù)調(diào)用傳入的參數(shù)列表急灭。
    綁定函數(shù)也可以使用new運(yùn)算符構(gòu)造姐浮,它會(huì)表現(xiàn)為目標(biāo)函數(shù)已經(jīng)被構(gòu)建完畢了似的。提供的this值會(huì)被忽略葬馋,但前置參數(shù)仍會(huì)提供給模擬函數(shù)卖鲤。
  • 語(yǔ)法
function.bind(thisArg[, arg1[, arg2[, ...]]])
  • 參數(shù)
    thisArg
    調(diào)用綁定函數(shù)時(shí)作為this參數(shù)傳遞給目標(biāo)函數(shù)的值。 如果使用new運(yùn)算符構(gòu)造綁定函數(shù)点楼,則忽略該值。當(dāng)使用bindsetTimeout中創(chuàng)建一個(gè)函數(shù)(作為回調(diào)提供)時(shí)白对,作為thisArg傳遞的任何原始值都將轉(zhuǎn)換為object掠廓。如果bind函數(shù)的參數(shù)列表為空,執(zhí)行作用域的this將被視為新函數(shù)的thisArg甩恼。
    arg1, arg2, ...
    當(dāng)目標(biāo)函數(shù)被調(diào)用時(shí)蟀瞧,預(yù)先添加到綁定函數(shù)的參數(shù)列表中的參數(shù)。
  • 返回值
    返回一個(gè)原函數(shù)的拷貝条摸,并擁有指定的this值和初始參數(shù)悦污。
  • 示例
var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
}

var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined

var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钉蒲,隨后出現(xiàn)的幾起案子切端,更是在濱河造成了極大的恐慌,老刑警劉巖顷啼,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踏枣,死亡現(xiàn)場(chǎng)離奇詭異昌屉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)茵瀑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門间驮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人马昨,你說(shuō)我怎么就攤上這事竞帽。” “怎么了鸿捧?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵屹篓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我笛谦,道長(zhǎng)抱虐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任饥脑,我火速辦了婚禮恳邀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灶轰。我一直安慰自己谣沸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布笋颤。 她就那樣靜靜地躺著乳附,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伴澄。 梳的紋絲不亂的頭發(fā)上赋除,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音非凌,去河邊找鬼举农。 笑死,一個(gè)胖子當(dāng)著我的面吹牛敞嗡,可吹牛的內(nèi)容都是我干的颁糟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喉悴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼棱貌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起箕肃,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤婚脱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體起惕,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涡贱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惹想。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片问词。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘀粱,靈堂內(nèi)的尸體忽然破棺而出激挪,到底是詐尸還是另有隱情,我是刑警寧澤锋叨,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布垄分,位于F島的核電站,受9級(jí)特大地震影響娃磺,放射性物質(zhì)發(fā)生泄漏薄湿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一偷卧、第九天 我趴在偏房一處隱蔽的房頂上張望豺瘤。 院中可真熱鬧,春花似錦听诸、人聲如沸坐求。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)桥嗤。三九已至,卻和暖如春仔蝌,著一層夾襖步出監(jiān)牢的瞬間泛领,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工敛惊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渊鞋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓豆混,卻偏偏與公主長(zhǎng)得像篓像,于是被迫代替她去往敵國(guó)和親动知。 傳聞我的和親對(duì)象是個(gè)殘疾皇子皿伺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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