首先说下前两者的区别。
call
和 apply
都是为了解决改变 this
的指向。作用都是相同的,只是传参的方式不同。
除了第一个参数外,call
可以接收一个参数列表,apply
只接受一个参数数组。
let a = { value: 1 } function getValue(name, age) { console.log(name) console.log(age) console.log(this.value) } getValue.call(a, 'yck', '24') getValue.apply(a, ['yck', '24'])
可以从以下几点来考虑如何实现
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 }
以上就是 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)) } }
本文作者:毛超颖
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!