js编程-重写call/bind

95 阅读1分钟

改变this的指向:Function.prototype: call/apply/bind

call/apply

  • 都是立即执行函数,并且改变函数中的this和传递参数。

  • 区别: 传递参数的区别,apply需要将传递的参数放到一个数组,而call是一个个传递,结果都是把这些参数一个个的传递给fn;

call: 在非严格模式下,context不传或者传递null/undefined,则this都改为window,严格模式下,不传是undefined,否则传递谁,就是谁。

重写call

/*
* 重写内置的call: 把需要执行的函数和需要改变的this关联在一起
*  +context.xxx = this;
*  + context.xxx() 类似于obj.fn()
*/
Function.prototype.call = function call(context, ...parmas) {
  context = context == null ? window : context;
  context = !/^(function|object)$/.test(typeof context) ? Object(context): context;
   let self = this,
       result = null,
       key = Symbol('key'); //新增的属性名保证唯一性,放置污染对象原有的成员
       context[key] = self;
       result = context[key](...params);
       delete context[key]; //用完后移除新增的成员
       return result;
}

重写bind

/*
* 重写bind : 柯里化思想 【参数预处理】
*/
Function.prototype.bind = function bind(context, ...outaArgs) {
   let self = this;
   return function(...innerArgs) {
     self.call(context, ...outerArgs.concat(innerArgs))
   }
}