call, apply, bind 區別
阿新 • • 發佈:2018-11-07
#call, apply, bind 區別及模擬實現call apply bind
三者都可以用來改變this的指向,但是在用法上略有不同
首先說一下call和apply的區別
call和apply都是第一個引數是this的指向 ,只是傳參的方式不同
call是 第二個以及第三依次類推都是當前函式的引數,每個引數用逗號相隔開
而apply則是將所有的引數以陣列的形式來傳遞的
call(window,引數1,引數1,引數3)
call和apply與bind的區別
call和apply相當於立即執行函式,使用時直接呼叫,而bind則類似於函式,使用時需要加()呼叫
同時bind傳參方式與call相同,引數都是一個一個傳遞的
模擬實現call
程式碼
Function.prototype.myCall = function (context) { var context = context || window // 給 context 新增一個屬性 // getValue.call(a, 'yck', '24') => a.fn = getValue context.fn = this// 將 context 後面的引數取出來 var args = [...arguments].slice(1) // getValue.call(a, 'yck', '24') => a.fn('yck', '24') var result = context.fn(...args) // 刪除 fn delete context.fn return result }
模擬實現apply 方式與call相似只是傳參方式不同
程式碼
Function.prototype.myApply = function (context) {var context = context || window context.fn = this var result // 需要判斷是否儲存第二個引數 // 如果存在,就將第二個引數展開 if (arguments[1]) { result = context.fn(...arguments[1]) } else { result = context.fn() } delete context.fn return result }
模擬實現bind
程式碼
Function.prototype.myBind = function (context) { if (typeof this !== 'function') { throw new TypeError('Error') } var _this = this var args = [...arguments].slice(1) // 返回一個函式 return function F() { // 因為返回了一個函式,我們可以 new F(),所以需要判斷 if (this instanceof F) { return new _this(...args, ...arguments) } return _this.apply(context, args.concat(...arguments)) } }