/** 目标:* 1. call、 apply、 bind作用及用法* 2. call、 apply、 bind三个方法有什么区别* */console.dir(Function.prototype);// 1. 事件函数中的 this 是绑定当前事件的元素// 2. 自执行函数中的 this 指向 window// 3. 定时器回调函数中的 this 指向 window// 4. 全局作用域中的 this 是 window// 5. 方法调用时,看方法名前面有没有点,有点的话,点前面是谁方法中的 this 就是谁,如果没有点,方法中的 this 就是 window// 6. 箭头函数中的 this 指向声明时所在作用域中的 this// 7. 构造函数中的 this 指向当前实例// 8. call / apply / bind 用来修改 this 指向function sum(a, b) { console.log(this); console.log(a, b); return a + b;}var obj = { id: '0511120117'};// sum(1, 2); // window// 1. call()// 作用: 修改函数中的 this 指向,并且把修改 this 后的函数执行// 语法:函数名.call(ctx, 实参1, 实参2.....)// 参数:ctx 就是用来替换函数中this的对象,从第二个参数起,都是传递给函数的实参// sum.call(obj, 2, 3); // call 之后,sum 中的 this 就变成了 obj// 模拟一个 call 方法~ function () { function call(context) { context = context || window; let args = [], result; for (let i = 1; i < arguments.length; i++) { args.push(arguments[i]); } context.$fn = this; result = context.$fn(...args); delete context.$fn; return result; } Function.prototype.call = call;}();// 基于 ES6 语法重构~function () { /*生成随机函数名:时间戳的方式*/ function queryRandomName () { let time = new Date().getTime(); return '$zhufeng' + time; } // 模拟 CALL 方法改变函数中的 THIS function changeThis(context = window,...arg){ let _this = this, result = null, ran = queryRandomName(); context[ran] = _this; result = context[ran](...arg); delete context[ran]; return result; }; Function.prototype.changeThis = changeThis;}();// 用 call 指定 undefined 和 null 作为 this 无效;// sum.call(undefined, 3, 4);// sum.call(null, 1, 3);// sum.call();// 2. apply()// apply 方法和 call 方法作用一样,修改函数中的 this,并且让这个修改 this 之后的函数执行;// 但是传参方式不同;call 方法是一个一个的传递实参给 sum 的,apply 是把实参都放到一个数组中,数组项是传递给 sum 的实参;// 模拟一个 apply 方法~function(){ /*生成随机函数名:时间戳的方式*/ function queryRandomName () { let time = new Date().getTime(); return '$zhufeng' + time; } function changeThis (context = window, arg = []) { let _this = this, result = null, ran = queryRandomName(); context[ran] = _this; result = context[ran](...arg); delete context[ran]; return result; }; Function.prototype.changeThis = changeThis;}();let res = fn.changeThis(obj,[100,200]);// sum.apply(obj, [11, 12]);// var ary = [1, 2, 3, 4, 5];// sum.apply(obj, ary);// 3. bind() 方法:// 作用:修改函数中的 this,返回一个修改 this 后的新函数;不会让函数执行。let sum2 = sum.bind(obj, 1, 2); // 传参的时候和 call 一样,需要一个一个的传console.log(sum2);console.log(sum === sum2); // false 因为 sum2 是一个新函数sum2(); // 修改 this 后,需要自己执行一次这个函数// call 和 apply 是修改 this 并且让函数执行,call 是一个一个的传参,apply 传递一个数组// bind 是只修改 this 返回修改 this 后的新函数,并不会让函数执行;
一、模拟call方法:图
二、阿里的一道面试题
// 阿里的面试题function fn1(){console.log(1);}function fn2(){console.log(2);}fn1.call(fn2);fn1.call.call(fn2);Function.prototype.call(fn1);Function.prototype.call.call(fn1);
