call()
、apply()
、bind()()
三种方法主要用来改变this
指向,区别在于三种方法的使用方式不同。
call(obj, ...)
方法通过以单个参数传入方式使用。注意:标红处
...
表示多个参数;以下代码仅测试方法是否能够使用,并没有测试传参问题。var a = 5; var obj = { a: 3, fun1: function () { console.log(this.a); } }; Function.prototype.myCall = function (context) { if (typeof this !== "function") { throw new TypeError(`This isn't a function!`); } context.fn = this; // 将调用myCall方法的函数赋值一份,这里指fun1函数 console.log(context.fn); var arr = []; for (var i = 1; i < arguments.length; i++) { arr.push("argument[" + i + "]"); } var result = eval("context.fn(" + arr + ")"); //重新生成一份fun1函数执行并返回结果给reuslt console.log(context.fn); delete context.fn; return result; }; var nFun1 = obj.fun1; nFun1.myCall(obj);
apply(obj, [...])
方法同样改变this
指针指向,不同的是它传入的一个数组var a = 5; var obj = { a: 3, fun1: function () { console.log(this.a); } }; Function.prototype.myApply = function (context, arr) { if (typeof this !== 'function') { throw new TypeError('this is not function!'); } context.fn = this; var result; if (!arr) { result = context.fn(); } else { var args = []; for (var i = 1; i < arguments.length; i++) { args.push('argument[' + i + ']'); } result = eval('context.fn(' + args + ')'); } delete context.fn; return result; }; var nFun1 = obj.fun1; nFun1.myApply(obj);
bind()()
方法使用方式通call()
类似