JS修改this指向有三种方法,call,bind,apply(这三个都是函数对象的方法,需要通过函数对象来调用,它们都是绑定在函数对象原型上面的方法),fun()是函数,则fun称为函数对象,调用语法示例:fun.call()
一. call
1.call函数的作用是调用函数,并且修改这个函数的this指向调用的对象
fun.call(thisArg,arg1,arg2,……)
thisArg:表示当前函数的this要指向的对象
arg1,arg2,……:表示普通参数
call方法内部的执行: 1.首先把call里面的第一个实参设置为调用这个方法的对象 2.把call方法第二个及之后的实参获取到 3.把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数
例子1(一个参数):修改fn方法的调用对象为o,意思就是对象o调用了fn.
1 function fn(){ 2 console.log('i want go to wc!'); 3 console.log(this); 4 } 5 //call的作用: 6 //1.调用函数 7 fn.call();//此时this指向的是window 8 //2.调用函数并修改this指向 9 //首先声明一个对象 10 var o ={ 11 name:'奥里给!' 12 } 13 fn.call(o);
运行结果:
例子2(多个参数):第一个参数意思为调用eat方法的对象,后面两个表示参数传入eat方法。
function eat(x,y){
console.log(x+y);
}
function drink(x,y){
console.log(x-y);
}
eat.call(drink,3,2);
输出:5
2.利用call实现继承
1 //父构造函数 2 function Father(name,age){ 3 //this指向父构造函数的对象实例 4 this.name = name ; 5 this.age = age; 6 } 7 //子构造函数 8 function Son(name,age){ 9 //调用父构造函数,并修改Father的this为儿子的this,以达到调用父方法 10 Father.call(this,name,18); 11 } 12 var wb = new Son('小王八',8) 13 console.log(wb);
运行结果:
二.apply
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。
语法格式:call(参数1,参数2,参数3),其中第一个参数为调用的对象
apply(参数1,[参数数组])
例子:fn.call(O,x,y) apply(O,[x,y])
function class1(args1,args2){ this.name=function(){ console.log(args,args); } } function class2(){ var args1="1"; var args2="2"; class1.call(this,args1,args2); /*或*/ //class1.apply(this,[args1,args2]); } var c=new class2(); c.name(); 输出:1 2
三. bind
- bind:语法和call一模一样,区别在于call立即执行,bind等待执行,bind是后面才有的,所以bind不兼容IE6~8
fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行 fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行
例子:this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined
document.onclick = fn.call(obj);
bind会把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行
document.onclick = fn.bind(obj);
总结:call与apply都可以改变this指向,参数传递方式不一样,都是立即调用函数,而bind用法与call一样,只不过不会立即执行,而是返回一个函数。