共计 2078 个字符,预计需要花费 6 分钟才能阅读完成。
call
、apply
、bind
作用是扭转函数执行时的上下文,简而言之就是扭转函数运行时的this
指向。- call 传入参数列表,apply 传入数组,然而都会立刻执行。
-
bind 传入参数列表,不会立刻执行,适宜在定时器等回调函数中应用。
let fun = dog.eat.bind(cat,'fish'); fun();
1、例子
- 代码中能够看到,失常状况
say
办法输入martin
。 -
然而咱们把
say
放在setTimeout
办法中,在定时器中是作为回调函数来执行的,因而回到主栈执行时是在全局执行上下文的环境中执行的,这时候this
指向window
,所以输入lucy
const name="lucy"; const obj={ name:"martin", say:function () {console.log(this.name); } }; obj.say(); //martin,this 指向 obj 对象 setTimeout(obj.say,0); //lucy,this 指向 window 对象
-
理论须要的是
this
指向obj
对象,这时候就须要该扭转this
指向了。setTimeout(obj.say.bind(obj),0); //martin,this 指向 obj 对象
2、区别
- 三者都能够扭转函数的
this
对象指向 - 三者第一个参数都是
this
要指向的对象,如果如果没有这个参数或参数为undefined
或null
,则默认指向全局window
- 三者都能够传参,然而
apply
是数组,而call
是参数列表,且apply
和call
是一次性传入参数,而bind
能够分为屡次传入 bind
是返回绑定 this 之后的函数,apply
、call
则是立刻执行
1)apply 办法
apply
承受两个参数,第一个参数是this
的指向,第二个参数是函数承受的参数,以数组的模式传入。-
扭转
this
指向后原函数会立刻执行,且此办法只是长期扭转this
指向一次。function fn(...args){console.log(this,args); } let obj = {myname:"张三"} fn.apply(obj,[1,2]); // this 会变成传入的 obj,传入的参数必须是一个数组;fn(1,2) // this 指向 window
-
当第一个参数为
null
、undefined
的时候,默认指向window
(在浏览器中)。fn.apply(null,[1,2]); // this 指向 window fn.apply(undefined,[1,2]); // this 指向 window
2)call 办法
call
办法的第一个参数也是this
的指向,前面传入的是一个参数列表。-
跟
apply
一样,扭转this
指向后原函数会立刻执行,且此办法只是长期扭转this
指向一次。function fn(...args){console.log(this,args); } let obj = {myname:"张三"} fn.call(obj,1,2); // this 会变成传入的 obj fn(1,2) // this 指向 window
-
同样的,当第一个参数为
null
、undefined
的时候,默认指向window
(在浏览器中)。fn.call(null,[1,2]); // this 指向 window fn.call(undefined,[1,2]); // this 指向 window
3)bind 办法
- bind 办法的第一参数也是
this
的指向,前面传入的也是一个参数列表(然而这个参数列表能够分屡次传入)。 -
扭转
this
指向后不会立刻执行,而是返回一个永恒扭转this
指向的函数。function fn(...args){console.log(this,args); } let obj = {myname:"张三"} const bindFn = fn.bind(obj); // this 也会变成传入的 obj,bind 不是立刻执行须要执行一次 bindFn(1,2) // this 指向 obj fn(1,2) // this 指向 window
3、基于 call 的继承
-
能够通过 call,子类能够应用父类的办法。
function Animal(){this.eat = function(){log("eating...") } } function Cat(){Animal.call(this); } let cat = new Cat(); cat.eat();
4、bind 的实现
-
bind 的实现
Function.prototype.myBind = function (context) { // 判断调用对象是否为函数 if (typeof this !== "function") {throw new TypeError("Error"); } // 获取参数 const args = [...arguments].slice(1); fn = this; return function Fn() { // 依据调用形式,传入不同绑定值 return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments)); } }
正文完
发表至: javascript
2023-01-01