国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

「干貨」細(xì)說 call、apply 以及 bind 的區(qū)別和用法

GraphQuery / 458人閱讀

摘要:的調(diào)用者,將會(huì)指向這個(gè)對(duì)象。此外,還可以擴(kuò)展自己的其他方法。的使用最后來說說。不同的是,方法的返回值是函數(shù),并且需要稍后調(diào)用,才會(huì)執(zhí)行。而和則是立即調(diào)用??偨Y(jié)和的主要作用,是改變對(duì)象的執(zhí)行上下文,并且是立即執(zhí)行的。

前言

上一篇文章 《「前端面試題系列4」this 的原理以及用法》 中,提到了 call 和 apply。

它們最主要的作用,是改變 this 的指向。在平時(shí)的工作中,除了在寫一些基礎(chǔ)類,或者公用庫(kù)方法的時(shí)候會(huì)用到它們,其他時(shí)候 call 和 apply 的應(yīng)用場(chǎng)景并不多。

不過,突然遇到的時(shí)候,需要想一下才能轉(zhuǎn)過彎來。所以今天,就讓我們好好地探究一下,這兩個(gè)方法的區(qū)別以及一些妙用。最后,還會(huì)介紹與之用法相似的 bind 的方法。

call 和 apply 的共同點(diǎn)

它們的共同點(diǎn)是,都能夠改變函數(shù)執(zhí)行時(shí)的上下文,將一個(gè)對(duì)象的方法交給另一個(gè)對(duì)象來執(zhí)行,并且是立即執(zhí)行的。

為何要改變執(zhí)行上下文?舉一個(gè)生活中的小例子:平時(shí)沒時(shí)間做飯的我,周末想給孩子燉個(gè)腌篤鮮嘗嘗。但是沒有適合的鍋,而我又不想出去買。所以就問鄰居借了一個(gè)鍋來用,這樣既達(dá)到了目的,又節(jié)省了開支,一舉兩得。

改變執(zhí)行上下文也是一樣的,A 對(duì)象有一個(gè)方法,而 B 對(duì)象因?yàn)槟撤N原因,也需要用到同樣的方法,那么這時(shí)候我們是多帶帶為 B 對(duì)象擴(kuò)展一個(gè)方法呢,還是借用一下 A 對(duì)象的方法呢?當(dāng)然是借用 A 對(duì)象的啦,既完成了需求,又減少了內(nèi)存的占用。

另外,它們的寫法也很類似,調(diào)用 call 和 apply 的對(duì)象,必須是一個(gè)函數(shù) Function。接下來,就會(huì)說到具體的寫法,那也是它們區(qū)別的主要體現(xiàn)。

call 和 apply 的區(qū)別

它們的區(qū)別,主要體現(xiàn)在參數(shù)的寫法上。先來看一下它們各自的具體寫法。

call 的寫法
Function.call(obj,[param1[,param2[,…[,paramN]]]])

需要注意以下幾點(diǎn):

調(diào)用 call 的對(duì)象,必須是個(gè)函數(shù) Function。

call 的第一個(gè)參數(shù),是一個(gè)對(duì)象。 Function 的調(diào)用者,將會(huì)指向這個(gè)對(duì)象。如果不傳,則默認(rèn)為全局對(duì)象 window。

第二個(gè)參數(shù)開始,可以接收任意個(gè)參數(shù)。每個(gè)參數(shù)會(huì)映射到相應(yīng)位置的 Function 的參數(shù)上。但是如果將所有的參數(shù)作為數(shù)組傳入,它們會(huì)作為一個(gè)整體映射到 Function 對(duì)應(yīng)的第一個(gè)參數(shù)上,之后參數(shù)都為空。

function func (a,b,c) {}

func.call(obj, 1,2,3)
// func 接收到的參數(shù)實(shí)際上是 1,2,3

func.call(obj, [1,2,3])
// func 接收到的參數(shù)實(shí)際上是 [1,2,3],undefined,undefined
apply 的寫法
Function.apply(obj[,argArray])

需要注意的是:

它的調(diào)用者必須是函數(shù) Function,并且只接收兩個(gè)參數(shù),第一個(gè)參數(shù)的規(guī)則與 call 一致。

第二個(gè)參數(shù),必須是數(shù)組或者類數(shù)組,它們會(huì)被轉(zhuǎn)換成類數(shù)組,傳入 Function 中,并且會(huì)被映射到 Function 對(duì)應(yīng)的參數(shù)上。這也是 call 和 apply 之間,很重要的一個(gè)區(qū)別。

func.apply(obj, [1,2,3])
// func 接收到的參數(shù)實(shí)際上是 1,2,3

func.apply(obj, {
    0: 1,
    1: 2,
    2: 3,
    length: 3
})
// func 接收到的參數(shù)實(shí)際上是 1,2,3
什么是類數(shù)組?

先說數(shù)組,這我們都熟悉。它的特征有:可以通過角標(biāo)調(diào)用,如 array[0];具有長(zhǎng)度屬性length;可以通過 for 循環(huán)或forEach方法,進(jìn)行遍歷。

那么,類數(shù)組是什么呢?顧名思義,就是具備與數(shù)組特征類似的對(duì)象。比如,下面的這個(gè)對(duì)象,就是一個(gè)類數(shù)組。

let arrayLike = {
    0: 1,
    1: 2,
    2: 3,
    length: 3
};

類數(shù)組 arrayLike 可以通過角標(biāo)進(jìn)行調(diào)用,具有l(wèi)ength屬性,同時(shí)也可以通過 for 循環(huán)進(jìn)行遍歷。

類數(shù)組,還是比較常用的,只是我們平時(shí)可能沒注意到。比如,我們獲取 DOM 節(jié)點(diǎn)的方法,返回的就是一個(gè)類數(shù)組。再比如,在一個(gè)方法中使用 arguments 獲取到的所有參數(shù),也是一個(gè)類數(shù)組。

但是需要注意的是:類數(shù)組無法使用 forEach、splice、push 等數(shù)組原型鏈上的方法,畢竟它不是真正的數(shù)組。

call 和 apply 的用途

下面會(huì)分別列舉 call 和 apply 的一些使用場(chǎng)景。聲明:例子中沒有哪個(gè)場(chǎng)景是必須用 call 或者必須用 apply 的,只是個(gè)人習(xí)慣這么用而已。

call 的使用場(chǎng)景

1、對(duì)象的繼承。如下面這個(gè)例子:

function superClass () {
    this.a = 1;
    this.print = function () {
        console.log(this.a);
    }
}

function subClass () {
    superClass.call(this);
    this.print();
}

subClass();
// 1

subClass 通過 call 方法,繼承了 superClass 的 print 方法和 a 變量。此外,subClass 還可以擴(kuò)展自己的其他方法。

2、借用方法。還記得剛才的類數(shù)組么?如果它想使用 Array 原型鏈上的方法,可以這樣:

let domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

這樣,domNodes 就可以應(yīng)用 Array 下的所有方法了。

apply 的一些妙用

1、Math.max。用它來獲取數(shù)組中最大的一項(xiàng)。

let max = Math.max.apply(null, array);

同理,要獲取數(shù)組中最小的一項(xiàng),可以這樣:

let min = Math.min.apply(null, array);

2、實(shí)現(xiàn)兩個(gè)數(shù)組合并。在 ES6 的擴(kuò)展運(yùn)算符出現(xiàn)之前,我們可以用 Array.prototype.push來實(shí)現(xiàn)。

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];

Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
bind 的使用

最后來說說 bind。在 MDN 上的解釋是:bind() 方法創(chuàng)建一個(gè)新的函數(shù),在調(diào)用時(shí)設(shè)置 this 關(guān)鍵字為提供的值。并在調(diào)用新函數(shù)時(shí),將給定參數(shù)列表作為原函數(shù)的參數(shù)序列的前若干項(xiàng)。

它的語法如下:

Function.bind(thisArg[, arg1[, arg2[, ...]]])

bind 方法 與 apply 和 call 比較類似,也能改變函數(shù)體內(nèi)的 this 指向。不同的是,bind 方法的返回值是函數(shù),并且需要稍后調(diào)用,才會(huì)執(zhí)行。而 apply 和 call 則是立即調(diào)用。

來看下面這個(gè)例子:

function add (a, b) {
    return a + b;
}

function sub (a, b) {
    return a - b;
}

add.bind(sub, 5, 3); // 這時(shí),并不會(huì)返回 8
add.bind(sub, 5, 3)(); // 調(diào)用后,返回 8

如果 bind 的第一個(gè)參數(shù)是 null 或者 undefined,this 就指向全局對(duì)象 window。

總結(jié)

call 和 apply 的主要作用,是改變對(duì)象的執(zhí)行上下文,并且是立即執(zhí)行的。它們?cè)趨?shù)上的寫法略有區(qū)別。

bind 也能改變對(duì)象的執(zhí)行上下文,它與 call 和 apply 不同的是,返回值是一個(gè)函數(shù),并且需要稍后再調(diào)用一下,才會(huì)執(zhí)行。

最后,分享一個(gè)在知乎上看到的,關(guān)于 call 和 apply 的便捷記憶法:

貓吃魚,狗吃肉,奧特曼打小怪獸。

有天狗想吃魚了

貓.吃魚.call(狗,魚)

狗就吃到魚了

貓成精了,想打怪獸

奧特曼.打小怪獸.call(貓,小怪獸)

貓也可以打小怪獸了

PS:歡迎關(guān)注我的公眾號(hào) “超哥前端小?!?,交流更多的想法與技術(shù)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/108876.html

相關(guān)文章

  • 「前端面試題系列6」理解函數(shù)柯里化

    摘要:原題如下寫一個(gè)方法,當(dāng)使用下面的語法調(diào)用時(shí),能正常工作這道題要考察的,就是對(duì)函數(shù)柯里化的理解。當(dāng)參數(shù)只有一個(gè)的時(shí)候,進(jìn)行柯里化的處理。這其實(shí)就是函數(shù)柯里化的簡(jiǎn)單應(yīng)用。 showImg(https://segmentfault.com/img/bVbopGm?w=620&h=350); 前言 這是前端面試題系列的第 6 篇,你可能錯(cuò)過了前面的篇章,可以在這里找到: ES6 中箭頭函數(shù)的...

    liaorio 評(píng)論0 收藏0
  • 細(xì)說apply callbind

    摘要:會(huì)創(chuàng)建一個(gè)新的函數(shù),成為綁定函數(shù),目標(biāo)函數(shù)和綁定函數(shù)有共同的函數(shù)體。新的目標(biāo)函數(shù)被調(diào)用的時(shí)候,就會(huì)綁定到函數(shù)的第一個(gè)參數(shù)上,且該參數(shù)不能被重寫。當(dāng)新的目標(biāo)函數(shù)被創(chuàng)建的時(shí)候,目標(biāo)函數(shù)的的值通過被設(shè)成了傳入的參數(shù)的值。 bind 概述 bind方法是綁定在了Function.prototype上。這個(gè)方法會(huì)創(chuàng)建一個(gè)新的函數(shù),當(dāng)被調(diào)用時(shí),會(huì)將其this關(guān)鍵字,設(shè)置為一個(gè)提供的值。 bind(...

    JasinYip 評(píng)論0 收藏0
  • 理解 JavaScript call()/apply()/bind()

    摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時(shí)決定的,指向被調(diào)用函數(shù)的對(duì)象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個(gè)新函數(shù)。這個(gè)新函數(shù)包裹了原函數(shù),并且綁定了的指向?yàn)閭魅氲摹? 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時(shí)決定的,...

    duan199226 評(píng)論0 收藏0
  • JavaScript 中 call、applybind 用法區(qū)別

    摘要:和類似,都是調(diào)用函數(shù),并指定函數(shù)的值和參數(shù),區(qū)別在于傳入?yún)?shù)是通過參數(shù)列表的形式,傳入?yún)?shù)是通過數(shù)組的形式方法與前兩個(gè)不同,它創(chuàng)建一個(gè)新的函數(shù),在調(diào)用新函數(shù)時(shí),會(huì)調(diào)用原函數(shù),并指定原函數(shù)的值和參數(shù)。執(zhí)行的時(shí)候并沒有調(diào)用函數(shù)。 簡(jiǎn)介 JavaScript 中有三個(gè)方法Function.prototype.call()、Function.prototype.apply()和Function...

    wind3110991 評(píng)論0 收藏0
  • 復(fù)習(xí)javascript中call,apply,bind用法

    摘要:綁定函數(shù)被調(diào)用時(shí),也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)。一個(gè)綁定函數(shù)也能使用操作符創(chuàng)建對(duì)象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。 一直很難理解js中的call apply bind,在w3schools,mdn閱讀了,也看了很多相關(guān)的文章,今天我來寫下我理解的call apply bind 首先創(chuàng)建一個(gè)函數(shù) function man(){} man.prototype = { name: ...

    darryrzhong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<