通过模拟 call apply bind来理解他们各自的用法和区别

2020-4-7 22:31:41
学习记录
72

通过模拟 call apply bind来理解他们的用法和区别

一句话解释call

call可以指定一个this和多个参数的情况下调用某个函数或者方法

  • 改变this指向
  • 传递多个参数
  • 立即执行

模拟call的实现

Call可以接受一个ctx对象,和一些参数,来调用这个方法,方法的this指向ctx

Function.prototype.call2 = function(ctx){ var ctx = ctx || window; var arg =[]; for(var i=1;i<arguments.length;i++){ arg.push('arguments['+i+']'); }; ctx.fn = this; if(arg.length>0){ var result = eval('ctx.fn('+arg+')'); }else{ var result = ctx.fn(); } delete ctx.fn; return result; }

一句话解释apply

apply可以接受一个ctx对象,和一个参数数组,来调用这个方法或函数,方法的this指向ctx

  • 改变this指向
  • 传递1个数组参数
  • 立即执行

applay用法

var obj = { v:1, a:2, b:3 } function bar(a,b){ console.log(this.v); console.log(a,b) } bar.apply(obj,['vvv','kkk']);

模拟apply的实现

Function.prototype.apply2 = function(ctx,arr){ ctx.fn = this; var ar = []; var res; if(arr){ for(var i=0;i<arr.length;i++){ ar.push('arr['+i+']'); } res = eval('ctx.fn('+ar+')'); }else{ res = ctx.fn(); } delete ctx.fn; return res; }

一句话解释bind

bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数

  • 返回一个函数
  • 可以传递多个参数
  • 参数可以再返回函数中传递剩余的
  • 作为函数调用可以改变this指向
  • 作为构造器使用,会忽略传递的第一个参数,this指向构造器

模拟bind

Function.prototype.bind2 = function (context) { if (typeof this !== "function") { throw new Error("Function.prototype.bind - what is trying to be bound is not callable"); } var self = this; var args = Array.prototype.slice.call(arguments, 1); var fNOP = function () {}; var fBound = function () { var bindArgs = Array.prototype.slice.call(arguments); return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs)); } fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }

通过模拟 call apply bind来理解他们的用法和区别

avatar

Sky(小新)

个人签名: 提升能力,创造价值!

江苏-南京
skylpz@qq.com