亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

怎么手寫實現bind函數

發布時間:2021-07-16 17:01:57 來源:億速云 閱讀:166 作者:chen 欄目:大數據

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

前面發了一篇文章,面試題目之原生實現call、apply、bind,這篇文章介紹了如何手動實現call、apply、bind,但是前不久重讀這篇文章時發現了實現bind的代碼不是很完善,我們看一段代碼:

function Person(){  this.name="zs";  this.age=18;  this.gender="男"}var obj={  hobby:"看書"}//  將構造函數的this綁定為objvar changePerson = Person.bind(obj);//  直接調用構造函數,函數會操作obj對象,給其添加三個屬性;changePerson();//  1、輸出objconsole.log(obj);
//  用改變了this指向的構造函數,new一個實例出來var p = new changePerson();// 2、輸出objconsole.log(p);

代碼輸出結果:

1、輸出:

怎么手寫實現bind函數

2、輸出:

怎么手寫實現bind函數

仔細觀察上面的代碼,再看輸出結果。

我們對Person類使用了bind將其this指向obj,得到了changeperson函數,此處如果我們直接調用changeperson會改變obj,若用new調用changeperson會得到實例 p,并且其__proto__指向Person,我們發現bind失效了。

我們得到結論:用bind改變了this指向的函數,如果用new操作符來調用,bind將會失效。

再看我們這篇文章(面試題目之原生實現call、apply、bind)中bind實現的代碼:


Function.prototype.myBind = function(ctx, ...argv1) {    return (...argv2) => {        return this.call(ctx, ...argv1, ...argv2)    }}

如果看不太習慣,將其轉化為es5的執行方式:

Function.prototype.mybind = function(){  // 1、保存函數  var _this = this;  // 2、保存目標對象  var context = arguments[0]||window;  // 3、保存目標對象之外的參數,將其轉化為數組;  var rest = Array.prototype.slice.call(arguments,1);  // 4、返回一個待執行的函數  return function F(){  // 5、將二次傳遞的參數轉化為數組;    var rest2 = Array.prototype.slice.call(arguments)    //6、用apply調用第一步保存的函數,并綁定this,傳遞合并的參數數組    _this.apply(context,rest.concat(rest2));  }}

我們用自己實現的mybind函數,來實現文章最上面的例子,測試一下如果,用mybind函數改變了構造函數的this,然后用new來執行生成的新函數,能否得到和原生bind一樣的效果,測試代碼如下:

function Person(){  this.name="zs";  this.age=18;  this.gender="男"}var obj={  hobby:"看書"}//  將構造函數的this綁定為obj ,此處調用上面開發的mybind方法;var changePerson = Person.mybind(obj);//  直接調用構造函數,函數會操作obj對象,給其添加三個屬性;changePerson();//  1、輸出objconsole.log(obj);
//  用改變了this指向的構造函數,new一個實例出來var p = new changePerson();// 2、輸出objconsole.log(p);

查看輸出結果:

1、輸出:

怎么手寫實現bind函數

2、輸出:

怎么手寫實現bind函數

我們用上面實現的mybind改變函數的this,然后調用new方法,發現并未實現和原生bind一樣的效果,我們實現的mybind方法和原生的bind實現的功能還有些差距,那么我們如何修正呢?

仔細觀察代碼,發現突破點再這里: new changeperson()。

這里我們只需要在調用 new changeperson()時候,判斷一下,是否是通過new操作符調用的,如果是new 操作符調用的話,我們就用new直接調用未改變this之前的函數,并返回其結果。

那么如何判斷是否是通過new操作符來調用一個函數呢?這里我們就要用到instanceof了,看看官方文檔對其解釋:


| instanceof運算符用于測試構造函數的prototype屬性是否出現在對象的

原型鏈中的任何位置。

翻譯成大白話,就是判斷某個實例是否由某個類或者構造函數生成。

回歸正文,我們知道,我們在用new操作符調用一個構造函數時,或者普通函數,都會在函數內部執行如下步驟:

1、生成一個空對象,

2、然后將this指向這個空對象,

3、最后將這個對象返回。

而這個對象就是這個構造函數的實例,那么只要在函數內部執行 this instanceof 構造函數 來判斷其結果是否為true,就能判斷函數是否是通過new操作符來調用了,若結果為true則是用new操作符調用的,代碼修正如下:

Function.prototype.mybind = function(){  // 1、保存函數  var _this = this;  // 2、保存目標對象  var context = arguments[0]||window;  // 3、保存目標對象之外的參數,將其轉化為數組;  var rest = Array.prototype.slice.call(arguments,1);  // 4、返回一個待執行的函數  return function F(){     // 5、將二次傳遞的參數轉化為數組;     var rest2 = Array.prototype.slice.call(arguments)    if(this instanceof F){      // 6、若是用new操作符調用,則直接用new 調用原函數,并用擴展運算符傳遞參數      return new _this(...rest2)    }else{           //7、用apply調用第一步保存的函數,并綁定this,傳遞合并的參數數組      _this.apply(context,rest.concat(rest2));    }  }}

此時,測試在運行上面的測試案例,打印結果為:

怎么手寫實現bind函數

完美實現了和原生bind一樣的效果,對一個知識點進行比較深入的研究確實不容易,越深入發現涉及的知識越廣泛,就像這篇文章,雖然說得是bind的手動實現,但是其實涉及了new操作符調用的原理,instanceof 的用法。

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

向AI問一下細節

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

AI

通州区| 陇南市| 榕江县| 普陀区| 吉安县| 大余县| 东平县| 都匀市| 浦县| 太和县| 莆田市| 临朐县| 瓦房店市| 庄浪县| 西华县| 同江市| 措美县| 资中县| 通州区| 余干县| 英超| 巢湖市| 普格县| 三明市| 大英县| 普兰店市| 建瓯市| 繁昌县| 济阳县| 资溪县| 庆元县| 通州市| 平原县| 泰宁县| 五常市| 句容市| 抚松县| 肇东市| 盐山县| 巴塘县| 新乡县|