前言:call、apply和bind都是为了改变某个函数运行时的this指向的,对于前端人员来说,关于this的掌握程度,直接决定了前端水平的高低。下面我们就来简单浅显易懂的来看一下es5中常用的三种修改this指向的方法。
1.call()方法
function test(m,n){ console.log(this.abc); } test();//这里打印的是undefined test.call({abc : 123});//这里打印的是123
如上代码所示,如果指定在全局环境下调用test方法,由于该函数是被window调用的,因此函数体内部的this是指向window的,但是window全局对象下又没有abc这个属性,因此打印出来的就是undefined(这里不考虑浏览器严格模式和非严格模式的区别)。
函数test如果是通过call方法来调用,那就不同了。call方法是每个函数建立的时候就有的方法,在调用call方法的时候,这个test函数会执行,同时函数体中的this的指向会自动修改指向到里面的对象了{abc:123},因此,打印的值就是123了。
function test(m,n){ console.log(this.abc); console.log(m); console.log(n); } test();//这里打印的是undefined test.call({abc : 123});//这里打印的是this.abc是123 test.call({abc : 123},100,200);//这里打印的this.abc是,m是100,n是200
ps:如上方的代码所示,另外call方法也可以传入其他的参数。
2.apply()方法
apply()方法与call方法用法基本相同,不同点主要是call()方法的第二个参数和之后的参数可以是任意数据类型,而apply的第二个参数是数组类型或者arguments参数集合。
function fn(a,b,c){ console.log(a,b,c); } fn.call(null,1,2,3);//打印的值是123 fn.apply(null,[1,2,3]);//打印的值是123
3.bind()方法(IE6,7,8不支持)
function test(m,n){ console.log(this.abc); } var test1 = test.bind({abc : 321});//这里修改test中的this指向为{abc:123},并且返回一个新函数并赋值给test1 test1();//这里打印321
bind()方法也能修改this指向,不过调用bind()方法不会执行test()函数,也不会改变test()函数本身,只会返回一个已经修改了this指向的新函数,这个新函数可以赋值给一个变量,调用这个变量新函数才能执行test1()。
如下方的代码所示,call()方法和bind()方法的区别在于1.bind的返回值是函数,并且不会自动调用执行,2.两者后面的参数的使用也不同。call 是 把第二个及以后的参数作为原函数的实参传进去,而bind 实参在其传入参数的基础上往后获取参数执行。
function fn(a,b,c){ console.log(a,b,c); } var fn1 = fn.bind({abc : 123},600); fn(100,200,300) //这里会输出--> 100,200,300 fn1(100,200,300) //这里会输出--> 600,100,200 fn1(200,300) //这里会输出--> 600,200,300 fn.call({abc : 123},600) //这里会输出--> 600,undefined,undefined
其实这里说的还只是修改this指向的一些方法,另外还可以使用不同环境定义不同this变量、es6里面的箭头函数等方法来修改this指向,这都要根据实际项目情况来决定使用哪种方式。如果你觉得这篇文章对你有帮助就点个赞吧