三者的异同点?
使用方法
函数.call(对象,arg1,arg2….)
函数.apply(对象,[arg1,arg2,…])
函数.bind(对象,arg1,arg2,….)
相同点
都可以改变this的指向,且第一个参数都是this将要指向的对象。
不同点
call和apply在使用时会自动执行函数,而bind不会执行。
你可以自己手动实现三种方法吗?
bind方法
概念:返回一个原函数的拷贝(也称绑定函数),在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
1 | function.bind(thisArg[, arg1[, arg2[, ...]]]) |
thisArg:调用绑定函数时作为this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,执行作用域的this将被视为新函数的thisArg。arg1, arg2, ...:当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
举例说明:
1 | window.value = 3; |
这个例子可以很好的理解bind的运用:
bar()直接调用函数,其中的value指的是全部变量value = 3bar.call(foo)这里使用call立刻改变了bar中的this指向为foo中bind常用于异步,在setTimeout中,设置的时间内,bar的this保留着指向foo,所以两秒后打印1,不是3。
前置知识:
MDN:绑定函数也可以使用 new 运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的 this 值会被忽略,但前置参数仍会提供给模拟函数。
特别说明:绑定函数被new实例化之后,需要继承原函数的原型链方法,且绑定过程中提供的this被忽略(继承原函数的this对象),但是参数还是会使用
代码实现
1 | const wang = { |
call方法
概念:function.call(thisArg, arg1, arg2, ...);
thisArg:在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。arg1, arg2, ...:指定的参数列表。
1 | var obj = { name:'segmentfault' }; |
理解:首先寻找call方法,通过原型链的查找,在Function.prototype上找到call方法;然后,改变fn函数中的this指向,将fn执行。
1 | var obj = { name:'wc' }; |
理解:带参数传入,参数需要展开,这也是唯一于apply方法不同的地方。
代码实现
1 | Function.prototype.myCall = function () { |
总结:
call方法的第一个参数用于改变调用call方法的函数内,this的指向,但是如果传入null/undefined值,此this会指向windowcall方法需要把实参按照形参的个数传进去call方法最后会使用参数去执行call函数体内this所指向的函数,一般是指向调用call的函数
apply方法
概念:调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
1 | func.apply(thisArg, [argsArray]) |
thisArg: 可选的。在func函数运行时使用的this值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null或undefined时会自动替换为指向全局对象,原始值会被包装。argsArray:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给func函数。如果该参数的值为null或undefined,则表示不需要传入任何参数。
代码实现
1 | const wang = { |
我很可爱,请给我钱



若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub IssuesGitHub Discussions