apply、call、bind 手写源码
1. apply:改变函数的 this 指向并立即调用,第一个参数是 this 指向,第二个参数为数组形式传入函数参数.
Function.prototype.apply = function (thisArg) { let context = thisArg || window; // window 必须在 .html 文件使用 let args = arguments[1] || []; context.fn = this; let result = context.fn(...args); delete context.fn; return result; }; // 测试 console.log(Math.min.apply(null ,[15,3,516,9,145]));
2. call:与 apply 作用基本相同,不同的是,call 的参数是一个个传入的,不是以数组形式直接传入.
Function.prototype.call = function (thisArg) { let context = thisArg || window; let args = []; for (let i = 1; i < arguments.length; i++) { args.push(arguments[i]); } context.fn = this; let result = context.fn(...args); delete context.fn; return result; } // 测试 console.log(Math.max.call(null, 15, 3, 65, 4, 2, 84));
或者利用已经实现的 apply 实现 call:
Function.prototype.call = function (thisArg) { let args = []; for (let i = 1; i < arguments.length; i++) { args.push(arguments[i]); } return this.apply(thisArg, args); };
3. bind:返回一个函数,与 apply 和 call 有所不同,bind 会使得原函数的 this 指向 thisArg,也就是说 apply 和 call 的 this 指向被改变后会立刻执行一次并返回结果,而 bind 返回绑定 this 指向的函数,不会立即执行这个函数.
Function.prototype.bind = function (thisArg) { let self = this; return function () { self.apply(thisArg, arguments); } };
var name = 'outer'; // let 定义的变量不会成为 window 的属性,因此使用 var 测试 let obj = { name: "inner" };
function printName() { console.log(this.name); }
printName(); // outer let printName_ = printName.bind(obj); printName_(); // inner

浙公网安备 33010602011771号