call、apply、bind 详解
三者都是改变函数执行时的上下文,也就是就是改变 this 的指向。
call(obj,arg1,arg2) //call()的参数一个一个的传
函数.call(第一个参数:想让函数中 this 指向谁,就传谁进来,
后面的参数:本身函数需要传递实参,需要几个实参,就一个一个的传递即可);
call 的作用: 1. 调用函数 2.指定函数中 this 指向
apply(obj,[arg1,arg2] //apply()的第二个参数则是一个数组
函数.apply(第一个参数:想让函数中 this 指向谁,就传谁进来,
第二个参数:要求传入一个数组,数组中包含了函数需要的实参)
apply 的作用: 1. 调用函数 2, 指定函数中 this 的指向
bind(this) // bind()返回的其实是一个函数,并不会立即执行。
函数.bind(第一个参数:想让函数中 this 指向谁,就传谁进来,
后面的参数:本身函数需要传递实参,需要几个实参,就一个一个的传递即可)
bind 的作用: 1. 克隆当前函数,返回克隆出来的新的函数
2. 新克隆出来的函数,这个函数的 this 被指定了
看下面例子就明白了:
1 2 3 4 5 6 7 8 9 10 11 12
| let obj = { name: "Thezero", say: function(){ return this.name } } let obj2 = { name: "萤火之森" } console.log(obj.say.apply(obj2)); / /萤火之森 console.log(obj.say.call(obj2)); console.log(obj.say.bind(obj2));
|
手写实现 call
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Function.prototype.myCall = function (myThis, ...args) { if (typeof this !== 'function') { throw new TypeError('not a function!'); } const fn = Symbol('fn'); myThis = myThis || window; myThis[fn] = this; const result = myThis[fn](...args); delete myThis[fn]; return result; };
|
手写实现 apply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Function.prototype.myApply = function (myThis, args = []) { if (typeof this !== 'function') { throw new TypeError('not a function!'); } const fn = Symbol('fn'); myThis = myThis || window; myThis[fn] = this; const result = myThis[fn](...args); delete myThis[fn]; return result; };
|
手写实现 bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Function.prototype.myBind = function (myThis, ...args) { if (typeof this !== 'function') { throw new TypeError('not a function!'); } const self = this; const fbound = function () { self.apply( this instanceof self ? this : myThis, args.concat(Array.prototype.slice.call(arguments)) ); }; fbound.prototype = Object.create(self.prototype); return fbound; };
|