call
call方法的特点:
一个函数通过.call()就相当于这个函数执行。
这个函数中 this 的指向就是call方法中的第一个参数。
call方法中从第二个参数开始之后,都是调用call方法函数的参数。
Function.prototype.myCall = function (ctx) {ctx = ctx ? Object(ctx) : window;ctx.originFn = this;var args = [];for (var i = 1; i < arguments.length; i ++) {args.push('arguments[' + i + ']');}console.log(args);var res = eval('ctx.origin(' + args + ')');delete ctx.originFn;return res;}
apply
apply方法的特点:
一个函数通过.apply()就相当于这个函数执行。
这个函数中 this 的指向就是call方法中的第一个参数。
apply方法的第二个参数是一个数组,里面是调用apply方法函数的参数。
apply方法只取到第二个参数,后面的忽略。
如果第二个参数是undefined、null、object、function,不报错但是arguments的length为0。
如果第二个参数是原始值,直接报错。
Function.prototype.myApply = function (ctx, args) {ctx = ctx ? Object(ctx) : window;ctx.originFn = this;if (args === undefined || args === null) {return ctx.originFn();}if (typeof args !== 'object' && typeof args !== 'function') {throw new Error('createListFormArrayLike called on non-object');}if (({}).toString.call(args) !== '[object Array]') {return ctx.originFn();}var res = eval('ctx.originFn(' + args + ')');delete ctx.originFn;return res;}
bind
bind方法的特点:
一个函数通过.bind()之后不会立即执行,而是返回一个新的函数。
这个函数中 this 的指向就是bind方法中的第一个参数。
bind方法从第二个参数开始,后面是调用bind方法函数的参数。
bind方法可以接收一部分参数,返回的新函数可以接收另一部分参数。
返回的新函数通过new执行(实例化),this指向原本的函数构造出来的实例。
实例继承原函数构造函数上的原型。
Function.prototype.myBind = function (ctx) {var originFn = this,args = [].slice.call(arguments, 1),_tempFn = function () {};var newFn = function () {var newArgs = [].slice.call(arguments),context = this instanceof newFn ? this : ctx;return originFn.apply(context, args.concat(newArgs));}_tempFn.prototype = originFn.prototype;newFn.prototype = new _tempFn();return newFn;}
