91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現call、apply、bind

發布時間:2022-01-05 16:12:12 來源:億速云 閱讀:130 作者:iii 欄目:大數據

本篇內容介紹了“怎么實現call、apply、bind”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

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

call方法在使用一個指定的 this 值和若干個指定的參數值的前提下調用某個函數或方法。

舉個例子:

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

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

總結如下:1、call改變函數this指向,2、調用函數

思考一下:我們如何實現上面的效果呢?代碼改造如下:

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

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

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

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

b、通過該對象的屬性調用該函數

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

代碼如下:

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

我們看一下上面的代碼:

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

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

3、處理參數,將傳入myCall的參數截取,去除第一位,然后轉為數組;

4、調用context.fn,此時fn的this指向context;

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

5、將結果返回。

以此類推,我們順便實現一下apply,唯一不同的是參數的處理,代碼如下:

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

以上便是call和apply的模擬實現,唯一不同的是對參數的處理方式。

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

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

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

根據上面的使用案例,我們先實現一個簡單版本的bind:

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

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

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

為了兼容bind調用時滿足參數傳遞的不同方式,代碼修改如下:

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)();

“怎么實現call、apply、bind”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南乐县| 焦作市| 色达县| 习水县| 蓝田县| 洛扎县| 克东县| 原平市| 施秉县| 太仓市| 广宗县| 红安县| 定西市| 颍上县| 平舆县| 彭阳县| 邯郸县| 绩溪县| 铜山县| 青冈县| 昭觉县| 北流市| 确山县| 那坡县| 浦县| 安阳县| 鲁山县| 池州市| 苍南县| 阜新市| 福贡县| 黎川县| 教育| 洞口县| 敖汉旗| 西乡县| 诸城市| 商都县| 会东县| 本溪市| 宁乡县|