了解this
this到底是什么呢?没有人能一句话概括,因为this总是在函数被调用的时候才被确定。因此,场景的不同会总成this指向的改变,但亘古不变的是,this总是指向执行这个函数的主体
this到底是谁?
那么,如何判断this到底指向什么呢?我画了个流程图,供大家参考:

this是谁取决于谁执行了这个函数,概括下来共有5种情况:
1.先看函数名前是否有“.”,有,前面是谁this就是谁;没有,则this指向window
function fn(){
console.log(this);
}
var obj={fn:fn};
fn();//this->window
obj.fn();//this->obj
function sum(){
fn();//this->window
}
sum();
var oo={
sum:function(){
console.log(this);//this->oo
fn();//this->window
}
};
oo.sum();
2.自执行函数中,this永远指向window
(function(){ //this->window })();
~function(){ //this->window }();
3.给元素绑定事件,方法中的this指向该元素
/* dom零级绑定 */
oDiv.onclick=function(){
//this->oDiv
};
/* dom二级时间绑定 */
oDiv.addEventListener("click",function(){
//this->oDiv
},false);
4.构造函数中的函数,它的this看谁调用,也就是谁"."了,那么this就只想谁了,如果没有,那么this就指向window
function CreateJsPerson(name,age){
//浏览器默认创建的对象就是我们的实例p1->this
this.name=name;//->p1.name=name
this.age=age;
this.writeJs=function(){
console.log("my name is"+this.name +",i can write Js");
};
//浏览器再把创建的实例默认的进行返回
}
var p1=new CreateJsPerson("尹华芝",48);
注意:如果不是"XX."的格式,那么this还是指向window,如下例:
function Fn(){
this.x=100;//this->f1
this.getX=function(){
console.log(this.x);//this->需要看getX执行的时候才知道
}
}
var f1=new Fn;
f1.getX();//->方法中的this是f1,所以f1.x=100
var ss=f1.getX;
ss();//->方法中的this是window ->输出undefined
5.call,apply,bind
1.call,apply和bind的区别
call,apply在将第一个参数变为this之后,会执行函数,而bind只负责绑定,不会自动执行
bind不执行
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.bind(a,1,2) //单绑定,未执行
b.bind(a,1,2)() //执行
call,apply在严格和非严格模式下,this指向的区别
call,apply修改this后,自动执行,且在严格和非严格模式下的this指向有所区别
var obj={name:"浪里行舟 "};
function fn(num1,num2){
console.log(num1+num2);
console.log(this);
}
fn.call(100,200);//this->100 num1=200 num2=undefined
fn.call(obj,100,200);//this->obj num1=100 num2=200
//在非严格模式下
fn.call();//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window
//严格模式下
fn.call();//在严格模式下this->undefined
fn.call(null);// 在严格模式 下this->null
fn.call(undefined);//在严格模式下this->undefined
call在非严格模式下,参数是null,undefined的情况下都会指向window
2.call和apply的区别
传参的区别:call第二个参数开始接受一个参数列表,apply第二个参数开始接受一个参数数组
fn.call(obj,100,200);
fn.apply(obj,[100,200]);
箭头函数的指向
箭头函数的this指向不是在函数被调用时才确定,而是在定义时确定
那么到底指向谁呢?简单来说,箭头函数的this取决于外部函数的this,如果外部第一层不是函数,那么指向window
第一例:this取决于外部函数的this
<button id="btn1">测试箭头函数this_1</button>
<button id="btn2">测试箭头函数this_2</button>
<script type="text/javascript">
let btn1 = document.getElementById('btn1');
let obj = {
name: 'kobe',
age: 39,
getName: function () {
btn1.onclick = () => {
console.log(this);//obj
};
}
};
obj.getName();
</script>
第一例:箭头函数外第一层不是函数,则指向window
<button id="btn1">测试箭头函数this_1</button>
<button id="btn2">测试箭头函数this_2</button>
<script type="text/javascript">
let btn2 = document.getElementById('btn2');
let obj = {
name: 'kobe',
age: 39,
getName: () => {
btn2.onclick = () => {
console.log(this);//window
};
}
};
obj.getName();
</script>