原生Javascript實現Bind
Bind:
bind() 方法會建立一個新函式。當這個新函式被呼叫時,bind() 的第一個引數將作為它執行時的 this,之後的一序列引數將會在傳遞的實參前傳入作為它的引數。(來自於 MDN )
接下來例子結合原始碼來分析:
//測試
var value = 2;
var foo = {
value: 1
};
function bar(name, age) {
this.habit = 'shopping';
console.log(this.value);
console.log(name);
console.log(age);
}
bar.prototype.friend = 'kevin';
var bindFoo = bar.bind(foo, 'daisy');
var obj = new bindFoo('18');
// undefined
// daisy
// 18
console.log(obj.habit);
console.log(obj.friend);
// shopping
// kevin
Function.prototype.myBind = function(context, ...args){
// 獲取自身的this,也就是 bar
let self = this;
let targetFuc = function(){
// 獲取繫結的函式的傳參,也就是 '18'
let targetArg = Array.prototype.call.slice(arguments)
// 以例子來看就是將bar的this指向context,也就是fo
// 正常來說是 self.apply(context,args.concat(targetArg)) 就行了
// 但是因為bind的返回可以用new繫結,new會改變this指向:
// 如果bind繫結後的函式被new了,那麼this指向會發生改變,指向當前函式的例項。也就是targetFuc
// this instanceof targetFuc 判斷返回的函式是否被new繫結在了例項上
// 因為bind()除了this還接收其他引數,bind()返回的函式也接收引數,這兩部分的引數都要傳給返回的函式
// args.concat(targetArg) 就相當於 ['daisy'].concat(['18])
return self.apply(this instanceof targetFuc ? this: context,args.concat(targetArg))
}
// 修改返回函式的 prototype 為繫結函式的 prototype,例項就可以繼承繫結函式的原型中的值,也就是friend和habit
targetFuc.prototype = Object.create(self.prototype);
return targetFuc
}
解釋就不多說了,看備註寫的很清楚
相關文章
- javascript之實現bindJavaScript
- ?徹底弄清 this call apply bind 以及原生實現APP
- JavaScript專題之模擬實現bindJavaScript
- JavaScript自我實現系列(2):call,apply,bindJavaScriptAPP
- JavaScript之call, apply, bind, new的實現JavaScriptAPP
- JavaScript bind()JavaScript
- 使用原生javascript實現jquery的$(function(){ })JavaScriptjQueryFunction
- JavaScript原生實現樓梯外掛JavaScript
- 原生Javascript實現星星評分元件JavaScript元件
- 細節解析 JavaScript 中 bind 函式的模擬實現JavaScript函式
- JavaScript 原生實現進度條元件.mdJavaScript元件
- 原生JavaScript實現造日曆輪子JavaScript
- javascript bind polyfillJavaScript
- 原生 JavaScript 實現 state 狀態管理系統JavaScript
- 原生javascript實現的選取搜尋元件JavaScript元件
- Javascript - apply、call、bindJavaScriptAPP
- 原生JavaScript實現頁面回到頂部的功能JavaScript
- JavaScript new 關鍵詞解析及原生實現 newJavaScript
- 【實戰】用原生的 JavaScript Intersection Observer API 實現 Lazy LoadingJavaScriptServerAPI
- JavaScript-apply、bind、callJavaScriptAPP
- 模擬實現apply/call/bindAPP
- call,apply,bind,new實現原理APP
- js call、apply、bind的實現JSAPP
- bind 函式的實現原理函式
- bind,call,apply模擬實現APP
- 根據JavaScript中原生的XMLHttpRequest實現jQuery的AjaxJavaScriptXMLHTTPjQuery
- 原生JavaScript實現的SPA單頁應用(hash路由)JavaScript路由
- 從零開始實現一個顏色選擇器(原生JavaScript實現)JavaScript
- bind/new/instanceof/assign模擬實現
- apply call bind的用法與實現APP
- 也談如何實現bind、apply、callAPP
- bind、call、apply區別?如何實現?APP
- 手把手教你實現boost::bind
- JavaScript重識bind、call、applyJavaScriptAPP
- [譯] Javascript: call()、apply() 和 bind()JavaScriptAPP
- JavaScript 中的 apply、call、bindJavaScriptAPP
- js深入之實現call、apply和bindJSAPP
- 使用Chrome開發者工具研究JavaScript裡函式的原生實現ChromeJavaScript函式