// 模拟实现call方法 Function.prototype.call2 = function (context) { var context = context || window; context.fn = this; var args = []; for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } var result = eval('context.fn(' + args +')'); delete context.fn return result; } // 测试一下 var value = 2; var obj = { value: 1 } function bar(name, age) { console.log(this.value); return { value: this.value, name: name, age: age } } bar.call(null); // 2 console.log(bar.call2(obj, 'kevin', 18));
// 模拟实现apply方法 Function.prototype.apply = function (context, arr) { var context = Object(context) || window; context.fn = this; var result; if (!arr) { result = context.fn(); } else { var args = []; for (var i = 0, len = arr.length; i < len; i++) { args.push('arr[' + i + ']'); } result = eval('context.fn(' + args + ')') } delete context.fn return result; }
// 模拟实现Bind方法 Function.prototype.bind = function (oThis) { var aArgs = Array.prototype.slice.call(arguments, 1); var fToBind = this; var fNOP = function () {}; var fBound = function () { fBound.prototype = this instanceof fNOP ? new fNOP() : fBound.prototype; return fToBind.apply(this instanceof fNOP ? this : oThis || this, aArgs ) } if( this.prototype ) { fNOP.prototype = this.prototype; } return fBound; }
三者的区别:
- 三者都是用来改变函数的
this
指向 - 三者的第一个参数都是
this
指向的对象 bind
是返回一个绑定函数可稍后执行,call
、apply
是立即调用- 三者都可以给定参数传递
call
给定参数需要将参数全部列出,apply
给定参数数组