一、函数的不同调用方式决定了this的指向不同,一般指向调用者
1.普通函数 this指向window的调用者
function fn(){
console.log('普通函数的this'+this);
}
window.fn();
2.对象的方法 this指向的是对象o (object)
var o={
sayHi:function(){
console.log('对象方法this:'+this);
}
}
o.sayHi();
3.构造函数 this指向ldh这个实例
原型对象里面的this指向的是ldh这个实例对象
function Star(){}
Star.prototype.sing=function(){ }
var ldh=new Star();
4.绑定事件函数this指向的是函数调用者 btn这个按钮对象
var btn=document.querySelector('button');
btn.onclick=function(){
console.log('绑定事件函数的this:'+this);
}
5.定时器函数 this 指向的也是window
window.setTimeout(function(){
console.log('定时器的this'+this);
},1000);
6.立即执行函数 this指向window
(function(){
console.log('立即执行函数的this'+this);
})();
二、改变函数内部的this指向
JavaScript为我们专门提供了一些函数方法帮我们处理函数内部this的指向问题,常用方法有
bind()、call()、apply()三种方法 ,call()方法调用一个对象,简单理解为调用函数的方式,但是
它可以改变函数的this指向
fun.call(thisArg,arg1,arg2);
1.call()
var o={
name:'any'
}
function fn(a,b){
console.log(this);
console.log(a+b);
}
fn.call(o,1,2);
//call第一个可以调用函数,第二个可以改变函数内的this指向
//call的主要作用可以实现继承
function Father(uname,age,sex){
this.uname=uname;
this.age=age;
this.sex=sex;
}
function Son(uname,age,sex){
Father.call(this,uname,age,sex);
}
var son=new Son('刘德华',19,'男');
console.log(son);
2.apply() 应用
var o={
name:'any'
}
function fn(arr){
console.log(this);
console.log(arr);//'pink'
}
fn.apply(o,['pink']);
//1.也是调用函数 第二个可以改变函数内部的this指向
//2.但是他的参数必须是数组(伪数组)
//3.apply的主要应用 比如说我们可以利用apply借助于
//数学内置对象求最大值
//Math.max();
var arr=[1,32,56,88];
//var max= Math.max.apply(null,arr);
var max= Math.max.apply(Math,arr);
var min= Math.min.apply(Math,arr);
console.log(max,min);
3.bind() 绑定
<button>点击</button>
<button>点击</button>
<button>点击</button>
var o={
name:'andy'
};
function fn(a,b){
console.log(this);
console.log(a+b);
};
var f= fn.bind(o,1,2);
f();
//1.不会调用原来的函数 可以改变原来函数内部的this指向
//2.返回的是原函数改变this之后产生的函数
//3.如果有的函数我们不需要立即调用,但是又想改变这个函数内部
//的this指向,此时用bind
var btn =document.querySelector('button');
btn.onclick=function(){
this.disabled=true;//this指向的是btn
//var that=this;
setTimeout(function(){
// that.disabled=false;//定时器函数里面的this指向window
this.disabled=false;//此时定时器函数里面的this指向的是btn
}.bind(this),3000)//这个this指向的是btn这个对象
}
var btns=document.querySelectorAll('button');
for(var i=0;i<btns.length;i++){
btns[i].onclick=function(){
this.disabled=true;
setTimeout(function(){
this.disabled=false;
}.bind(this),3000)
}
}
三、call apply bind总结
相同点:
都可以改变函数内部的this指向
区别点:
1.call和apply会调用函数并且改变函数内部的this指向
2.call和apply传递的参数不一样,call传递参数aru1、aru2形式
apply必须数组形式[arg]
3.bind不会调用函数,可以改变函数内部的this指向。
主要应用场景:
1.call经常做继承
2.apply经常跟数组有关系,比如借助数学对象实现数组最大值和最小值
3.bind不调用函数,但是还是想改变this指向,比如改变定时器内部的this指向。