bind函式 模擬實現JS的bind方法

2021-10-11 06:08:47 字數 3002 閱讀 4408

先看一下bind是什麼?

var obj = {};obj;typeof function.prototype.bind; // functiontypeof function.prototype.bind(); // functionfunction.prototype.bind.name; // bindfunction.prototype.bind().name; // bound console.dir(function.prototype.bind()); // 可以自行在瀏覽器控制台列印看看// f bound ()// length: 0// name: "bound "
因此可以得出結論1:1、bind是functoin原型鏈中function.prototype的乙個屬性,每個函式都可以呼叫它。

2、bind本身是乙個函式名為bind的函式,返回值也是函式,函式名是bound 。(打出來就是bound加上乙個空格)。 知道了bind是函式,就可以傳參,而且返回值'bound '也是函式,也可以傳參,就很容易寫出例子2:

後文統一 bound 指原函式original bind之後返回的函式,便於說明。

var obj = ;function original(a, b)var bound = original.bind(obj, 1);var boundresult = bound(2); // 'test', [1, 2]boundresult; // falseoriginal.bind.name; // 'bind'original.bind.length; // 1original.bind().length; // 2 返回original函式的形參個數bound.name; // 'bound original'(function(){}).bind().name; // 'bound '(function(){}).bind().length; // 0
由此可以得出結論2:1、呼叫bind的函式中的this指向bind()函式的第乙個引數。

2、傳給bind()的其他引數接收處理了,bind()之後返回的函式的引數也接收處理了,也就是說合併處理了。

3、並且bind()後的name為bound + 空格 + 呼叫bind的函式名。如果是匿名函式則是bound + 空格。

4、bind後的返回值函式,執行後返回值是原函式(original)的返回值。

5、bind函式形參(即函式的length)是1。bind後返回的bound函式形參不定,根據繫結的函式原函式(original)形參個數確定。

根據結論2:我們就可以簡單模擬實現乙個簡版bindfn

我們知道函式是可以用new來例項化的。那麼bind()返回值函式會是什麼表現呢

var obj = ;function original(a, b) console.log('typeof this', typeof this); // object this.name = b; console.log('name', this.name); // 2 console.log('this', this); // original  console.log([a, b]); // 1, 2}var bound = original.bind(obj, 1);var newboundresult = new bound(2);console.log(newboundresult, 'newboundresult'); // original  this指向了new bound()生成的新物件。
可以分析得出結論3:1、bind原先指向obj的失效了,其他引數有效。

2、new bound的返回值是以original原函式構造器生成的新物件。original原函式的this指向的就是這個新物件,new做了什麼?

1.建立了乙個全新的物件。

2.這個物件會被執行[[prototype]](也就是__proto__)鏈結。

3.生成的新物件會繫結到函式呼叫的this。

4.通過new建立的每個物件將最終被[[prototype]]鏈結到這個函式的prototype物件上。

5.如果函式沒有返回物件型別object(包含functoin, array, date, regexg, error),那麼new表示式中的函式呼叫會自動返回這個新的物件。

所以相當於new呼叫時,bind的返回值函式bound內部要模擬實現new實現的操作。

注釋中提到this instanceof bound也不是很準確,es6 new.target很好的解決這一問題

function student(name) else}var student = new student('軒轅');var notastudent = student.call(student, 'rowboat'); // 不丟擲錯誤,且執行了。console.log(student, 'student', notastudent, 'notastudent');function student2(name) else}var student2 = new student2('軒轅');var notastudent2 = student2.call(student2, 'rowboat');console.log(student2, 'student2', notastudent2, 'notastudent2'); // 丟擲錯誤
細心的同學可能會發現了這版本的**沒有實現bind後的bound函式的namemdn function.name和lengthmdn function.length

object.defineproperties(bound, , 'name': });
最後es5-shim的原始碼實現bind,直接附上原始碼(有刪減注釋和部分修改等)

bind函式模擬實現

console.log function.prototype.bind function console.log function.prototype.bind function console.log function.prototype.bind.name bind console.log fu...

bind的模擬實現

var context context window var result 判斷是否有第二個引數 if arguments 1 else delete context.fn return result var foo function bar name,age bind 方法會建立乙個新的函式。當這...

深入JavaScript 模擬實現bind

bind bind 方法會建立乙個新函式。當這個新函式被呼叫時,bind 的第乙個引數將作為它執行時的 this,之後的一串行引數將會在傳遞的實參前傳入作為它的引數。由此我們可以首先得出 bind 函式的兩個特點 例1var foo function bar var bindfoo bar.bind...