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

資訊專欄INFORMATION COLUMN

模擬實現bind方法

array_huang / 2098人閱讀

摘要:前言最近接觸到方法,為了加深理解,自己模擬實現一下。我們模擬的方法參考上的。基本上關于模擬的實現就是這樣。所以不能肯定剛才的就是總結完全重寫構造函數原型對象要放在構造函數后面,如果放在構造函數里面,可能原型鏈會有錯誤。

前言

最近接觸到bind方法,為了加深理解,自己模擬實現一下。

首先,談一下bind()方法的特點:

把調用bind()的函數(以后統稱為初試函數)中的this指向綁定到某個對象上,bind的第二個及其以后的參數作為作為 初始函數的 參數,bind()執行完返回一個新的函數。

新返回的函數如果用 new 字符來調用的話,那么之前this指向綁定到某個對象上 將會失效,并且初始函數中的this指向綁定到 new調用的 函數實例上。函數實例上還可以調用初始函數的原型上的方法

那么先實現第一個特點

// 因為需要所有函數都能執行,所以綁定到Function.prototype上
Function.prototype.bindFn=function(thisArg) {
   if(typeof this !== "function") {
         throw new TypeError(this+" is not a function");
   }
   
   // 調用bindFn方法的函數的引用
   var self = this;
   // 以數組形式保存第二個及其以后的參數
   var beforeArg = [].slice.call(arguments,1);

   var bound = function() {
        // 以數組形式保存著當前函數的所有參數
        var afterArg = [].slice.call(arguments);
        // bindFn第二個及其以后的參數和當前函數所有參數的 集合
        // 全部傳到self函數的參數里
        var finalArgs = beforeArg.concat(afterArg);
        // self中的this指向綁定到 thisArg
        return  self.apply(thisArg, finalArgs);
   }
   return bound;
}
var obj1={sex:23};

function m1(a,b) {
    console.log(a+b); // 6
    console.log(this); // {sex:23}
}

var bound=m1.bindFn(obj1,2);
var result=bound(4); 

可見m1中的this指向了obj1對象,2,4分別傳給了形參a,b。

進一步完善bindFn,實現第二個特點

// 因為需要所有函數都能執行,所以綁定到Function.prototype上
Function.prototype.bindFn=function(thisArg) {
   if(typeof this !== "function") {
         throw new TypeError(this +" is not a function");
   }
   
   // 調用bindFn方法的函數的引用
   var self = this;
   // 以數組形式保存第二個及其以后的參數
   var beforeArg = [].slice.call(arguments,1);

   var bound = function() {
        // 以數組形式保存著當前函數的所有參數
        var afterArg = [].slice.call(arguments);
        // bindFn第二個及其以后的參數和當前函數所有參數的 集合
        // 全部傳到self函數的參數里
        var finalArgs = beforeArg.concat(afterArg);
        // 如果new調用的話,this指向實例對象
        // 否則this指向需要綁定的對象
        // this instanceof bound并不準確,可以用es6中的new.target來解決
        return  self.apply(this instanceof bound ? this : thisArg, finalArgs);
   }
   
   // new調用的時候有用
   // 避免es6中的箭頭函數
   // 箭頭函數沒有prototype
   if(this.prototype) {
         // 避免修改 bound.prototype 污染到 this.prototype
      function a(){}
      a.prototype=this.prototype;
      bound.prototype=new a();
      bound.prototype.constructor=bound;
   }
   return bound;
}
var obj1={sex:23};

function m1(a,b) {
    this.name="m1";
    console.log(a+b); // 6
    console.log(this); // {name:"m1"}
}

m1.prototype.allKey=function() {
    console.log("this is allkey");
}

var bound=m1.bindFn(obj1,2);
var result=new bound(4); 
result.allKey(); // this is allkey

可見,m1中的this指向了result這個實例對象,并且result 通過原型鏈 繼承了m1.prototype上的方法。

那么我們看下官方bind的使用:

// 關鍵部分
function m1(a,b) {
    this.name="m1";
    console.log(a+b); // 6
    console.log(this); // {name:"m1"}
}
var bound=m1.bind(obj1,2);
var result=new bound(4); 
result.allKey(); // this is allkey

由上圖可見,雖然原型鏈上有所不同,但我們模擬的方法還是實現了bind的功能。我們模擬的方法bindFn參考mdn上的Polyfill。基本上關于模擬bind的實現就是這樣。

現在我們在延伸一下關于原型鏈的知識,如果剛才的bound.prototype完全重寫在了bound構造函數內,又會怎樣?

// 因為需要所有函數都能執行,所以綁定到Function.prototype上
Function.prototype.bindFn=function(thisArg) {
   if(typeof this !== "function") {
         throw new TypeError(this +": is not a function");
   }
   
   // 調用bindFn方法的函數的引用
   var self = this;
   // 以數組形式保存第二個及其以后的參數
   var beforeArg = [].slice.call(arguments,1);

   var bound = function() {
        // 以數組形式保存著當前函數的所有參數
        var afterArg = [].slice.call(arguments);
        // bindFn第二個及其以后的參數和當前函數所有參數的 集合
        // 全部傳到self函數的參數里
        var finalArgs = beforeArg.concat(afterArg);
        // 用new 方式調用
        if(this instanceof bound) {
             // 避免es6箭頭函數
             // 箭頭函數沒有prototype
         if(self.prototype) {
                 // 避免修改 bound.prototype 污染到 self.prototype
              function a(){}
              a.prototype=self.prototype;
              bound.prototype=new a();
              bound.prototype.constructor=bound;
            
         }
         // self中的this指向 new生成的實例對象
            return self.apply(this,finalArgs);
        }
        // 無new 調用方式, self中的this指向thisArg
        return  self.apply(thisArg, finalArgs);
   }
     bound.prototype.getKey=function() {

              }
   return bound;
};
var obj1={sex:23};

function m1(a,b) {
    this.name="m1";
    console.log(a+b); // 6
    console.log(this);  
}

m1.prototype.allKey=function() {
    console.log("this is allkey");
}

var bound=m1.bindFn(obj1,2);
var result=new bound(4); 
result.allKey(); // 報錯 result.allKey is not a function

按理說 result原型鏈上應該有allKey方法的,結果卻報錯了,我們把m1中的this打印一下看看

這里我們看到原型鏈上并沒有m1.prototype, 所以在構造函數內部 完全重寫 構造函數原型對象的話,原型鏈會與預想的不同。

那么圖上的bound.prototype打個 ? ,因為并不確定這個是bound.prototype,如果真是bound.prototype的話,那么下面的話如何解釋?

console.log(result.__proto__ === bound.prototype ) // false

按理說 result.__proto__ 指向的是bound.prototype,結果卻為false。所以不能肯定剛才的就是bound.prototype

總結: 完全重寫構造函數原型對象 要放在構造函數后面,如果放在構造函數里面,可能原型鏈會有錯誤。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99462.html

相關文章

  • 【進階3-4期】深度解析bind原理、使用場景及模擬實現

    摘要:返回的綁定函數也能使用操作符創建對象這種行為就像把原函數當成構造器,提供的值被忽略,同時調用時的參數被提供給模擬函數。 bind() bind() 方法會創建一個新函數,當這個新函數被調用時,它的 this 值是傳遞給 bind() 的第一個參數,傳入bind方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。bind返回的綁定函數也能使用 n...

    guyan0319 評論0 收藏0
  • JavaScript專題之模擬實現bind

    摘要:但是三作為構造函數時函數其實還有一個非常重要的特點返回的函數如果作為構造函數,搭配關鍵字出現的話,我們的綁定就需要被忽略。其次,當返回的函數作為構造函數時,之前綁定的會失效。 本文共 1100 字,讀完只需 4 分鐘 概述 前一篇文章我們嘗試模擬實現了 call 和 apply 方法,其實 bind 函數也可以用來改變 this 的指向。bind 和 call和 apply 兩者的區別...

    劉明 評論0 收藏0
  • 面試官問:能否模擬實現JS的bind方法

    摘要:點擊那么面試官可能會問是否想過到底做了什么,怎么模擬實現呢。另外前不久寫過一篇文章面試官問能否模擬實現的操作符。所以相當于調用時,的返回值函數內部要模擬實現實現的操作。文章中的例子和測試代碼放在中模擬實現。 前言 用過React的同學都知道,經常會使用bind來綁定this。 import React, { Component } from react; class TodoItem ...

    Julylovin 評論0 收藏0
  • JavaScript深入之bind模擬實現

    摘要:也就是說當返回的函數作為構造函數的時候,時指定的值會失效,但傳入的參數依然生效。構造函數效果的優化實現但是在這個寫法中,我們直接將,我們直接修改的時候,也會直接修改函數的。 JavaScript深入系列第十一篇,通過bind函數的模擬實現,帶大家真正了解bind的特性 bind 一句話介紹 bind: bind() 方法會創建一個新函數。當這個新函數被調用時,bind() 的第一個參數...

    FingerLiu 評論0 收藏0
  • call、bind模擬實現

    摘要:大致就是這樣所以可以模擬實現和。這些參數作為的第二個參數跟在后面,之后它們會被插入到目標函數的參數列表的開始位置,傳遞給綁定函數的參數會跟在它們的后面。 一個前端知識點匯總綜合了學習過程中的知識點,比如this、閉包、BFC、ES6等,如果大佬們覺得還可以的話,求個star啦! call和apply 每個函數都包含兩個非繼承而來的方法:apply()和call() 用途相同,都是在...

    mmy123456 評論0 收藏0
  • JavaScript進階之模擬call,apply和bind

    摘要:模擬和模擬一樣,現摘抄下面的代碼添加一個返回值對象然后我們定義一個函數,如果執行下面的代碼能夠返回和函數一樣的值,就達到我們的目的。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 目的 本文主要用于理解和掌握call,apply和bind的使用和原理,本文適用于對它們的用法不是很熟悉,或者想搞清楚它們原理的童鞋。 好,那我們開始...

    CoderBear 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<