内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

怎么實現(xiàn)call、apply、bind

本篇內(nèi)容介紹了“怎么實現(xiàn)call、apply、bind”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)成都網(wǎng)站建設(shè)定制制作,是成都網(wǎng)站建設(shè)公司,為成都茶樓設(shè)計提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計、前端HTML5制作、后臺程序開發(fā)等。成都網(wǎng)站改版熱線:13518219792

首先我們來給call下個定義:

call方法在使用一個指定的 this 值和若干個指定的參數(shù)值的前提下調(diào)用某個函數(shù)或方法。

舉個例子:

var foo = {    value: 1};
function bar() {    console.log(this.value);}
bar.call(foo); // 1

從上面代碼的執(zhí)行結(jié)果,我們可以看到,call首先改變了this的指向,使函數(shù)的this指向了foo,然后使bar函數(shù)執(zhí)行了。

總結(jié)如下:1、call改變函數(shù)this指向,2、調(diào)用函數(shù)

思考一下:我們?nèi)绾螌崿F(xiàn)上面的效果呢?代碼改造如下:

//將bar函數(shù)掛載到foo對象上,使其成為foo的方法,用foo.bar來調(diào)用var foo = {    value:1,    bar:function(){        console.log(this.value)    }}foo.bar()     //1

仔細觀察一下我們做了什么,將bar函數(shù)掛載到foo對象上,使其成為foo的方法,用foo.bar來調(diào)用。

再來看上面代碼的執(zhí)行結(jié)果:打印1,有沒有什么啟發(fā)呢?為了模擬call方法,我們可不可以這樣做呢:

a、將函數(shù)設(shè)為某個對象的屬性(或者方法)

b、通過該對象的屬性調(diào)用該函數(shù)

c、將該對象上的這個屬性(或者方法)

代碼如下:

Function.prototype.myCall = function(context) {  context = context || window  //將函數(shù)掛載到對象的fn屬性上  context.fn = this  //處理傳入的參數(shù)  const args = [...arguments].slice(1)  //通過對象的屬性調(diào)用該方法  const result = context.fn(...args)  //刪除該屬性  delete context.fn  return result}

我們看一下上面的代碼:

1、首先我們對參數(shù)context做了兼容處理,不傳值,context默認值為window。

2、然后我們將函數(shù)掛載到context上面,context.fn = this;

3、處理參數(shù),將傳入myCall的參數(shù)截取,去除第一位,然后轉(zhuǎn)為數(shù)組;

4、調(diào)用context.fn,此時fn的this指向context;

5、刪除對象上的屬性 delete context.fn

5、將結(jié)果返回。

以此類推,我們順便實現(xiàn)一下apply,唯一不同的是參數(shù)的處理,代碼如下:

Function.prototype.myApply = function(context) {
 context = context || window  context.fn = this  let result    // myApply的參數(shù)形式為(obj,[arg1,arg2,arg3]);    // 所以myApply的第二個參數(shù)為[arg1,arg2,arg3]    // 這里我們用擴展運算符來處理一下參數(shù)的傳入方式  if (arguments[1]) {    result = context.fn(...arguments[1])  } else {    result = context.fn()  }  delete context.fn  return result}

以上便是call和apply的模擬實現(xiàn),唯一不同的是對參數(shù)的處理方式。

接著再來思考一下bind的實現(xiàn),在模擬bind的實現(xiàn)之前,先看一下bind的使用案例:

var obj = {a:1};function bar(){    console.log(this.a);}bar.bind(obj)();

我們看到,bind函數(shù)雖然也能改變bar函數(shù)的this,但是改變后,函數(shù)并不會執(zhí)行,只是返回一個新的函數(shù),想執(zhí)行就得繼續(xù)調(diào)用,仔細觀察第五行代碼的寫法。

根據(jù)上面的使用案例,我們先實現(xiàn)一個簡單版本的bind:

Function.prototype.myBind = function(ctx) {    return () => { // 要用箭頭函數(shù),否則 this 指向錯誤        return this.call(ctx)    }}var obj = {a:1};function bar(){    console.log(this.a);}bar.myBind(obj)();

但是這樣比較簡陋,函數(shù)的參數(shù)一多就不能處理了,如下面這種情況:

bar.bind(obj, 2)(2)// orbar.bind(obj)(2, 2)

為了兼容bind調(diào)用時滿足參數(shù)傳遞的不同方式,代碼修改如下:

Function.prototype.myBind = function(ctx, ...argv1) {    return (...argv2) => {        return this.call(ctx, ...argv1, ...argv2)    }}//測試代碼var obj = {a:1};function bar(b,c){    console.log(this.a+b+c);}bar.myBind(obj)(20,30);bar.myBind(obj,20,30)();

“怎么實現(xiàn)call、apply、bind”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

本文標(biāo)題:怎么實現(xiàn)call、apply、bind
本文URL:http://www.rwnh.cn/article16/jisgdg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、網(wǎng)站內(nèi)鏈移動網(wǎng)站建設(shè)、企業(yè)建站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
上犹县| 原平市| 太白县| 老河口市| 石林| 隆化县| 隆昌县| 盱眙县| 阜宁县| 普定县| 梁山县| 察雅县| 安溪县| 松溪县| 缙云县| 隆德县| 建始县| 苍南县| 胶南市| 商洛市| 息烽县| 祁门县| 电白县| 咸丰县| 新竹市| 海林市| 襄汾县| 六枝特区| 绥阳县| 甘孜县| 洛南县| 连云港市| 永年县| 安仁县| 棋牌| 五河县| 新晃| 云阳县| 太原市| 如皋市| 綦江县|