call、apply、bind的區別,模擬call、apply和bind的實現
阿新 • • 發佈:2018-12-08
bind:bind繫結完this的指向後會返回一個新的函式體,不會被立即呼叫
call&apply:繫結完this的指向後會立即呼叫
call與apply的區別:
call:第一個引數是this的指向,第二個以及後面的所有引數需要一個個進行傳遞
apply:第一個引數是this的指向,第二個引數是一個數組
apply:第一個引數是this的指向,第二個引數是一個數組
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.fnreturn result }
以上就是 call
的思路,apply
的實現也類似
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
和其他兩個方法作用也是一致的,只是該方法會返回一個函式。並且我們可以通過 bind
實現柯里化。
同樣的,也來模擬實現下 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)) } }
如何準確的判斷一個物件是一個什麼型別的?
1、typeof 2、instanceof
3、Object.prototype.toString.call() var arr = [10,20,03,04]; var fn = function(){} var img = new Image() var d = new Date() console.log(arr.toString()) console.log(Object.prototype.toString.call(d))