call

  1. Function.prototype.myCall = function(context) {
  2. if (typeof this !== 'function') {
  3. throw new TypeError('Error')
  4. }
  5. context = context || window
  6. context.fn = this
  7. const args = [...arguments].slice(1)
  8. const result = context.fn(...args)
  9. delete context.fn
  10. return result
  11. }

apply

  1. Function.prototype.myApply = function(context) {
  2. if (typeof this !== 'function') {
  3. throw new TypeError('Error')
  4. }
  5. context = context || window
  6. context.fn = this
  7. let result
  8. // 处理参数和 call 有区别
  9. if (arguments[1]) {
  10. result = context.fn(...arguments[1])
  11. } else {
  12. result = context.fn()
  13. }
  14. delete context.fn
  15. return result
  16. }

bind

  1. Function.prototype.myBind = function (context) {
  2. if (typeof this !== 'function') {
  3. throw new TypeError('Error')
  4. }
  5. const _this = this
  6. const args = [...arguments].slice(1)
  7. // 返回一个函数
  8. return function F() {
  9. // 因为返回了一个函数,我们可以 new F(),所以需要判断
  10. if (this instanceof F) {
  11. return new _this(...args, ...arguments)
  12. }
  13. return _this.apply(context, args.concat(...arguments))
  14. }
  15. }