详解 JavaScript 中 this 机制

一、前言

JavaScript中this根据所处的执行环境不同而有所不同;听上去好像一头雾水,但是只要找到关键点——执行环境,或者通俗一点说就是被谁调用,你就能很容易的理解它,下面通过几个方面来具体说明:

二、this 的几种情况

1. 全局环境

//案例1
var a=function(){
console.log(this);//Window
};
a();

//案例2
var a=function(){
    console.log(this);//Window
return function(){
    console.log(this);//Window
}
};
a()();

说明:

案例1:a函数的执行环境是全局,a()可以理解为是window.a(),即被window对象调用,所以this指向window。

案例2:此案例可能稍微有点复杂,似乎看不到到底谁在调用,可以变形一下,var x=a();x();这时候的x的执行环境也是全局,故this也指向window。

2. 对象环境

var a={
   print:function(){
    console.log(this); //对象a
   };
}
a.print();

说明:以上print()方法是由a调用的,所以this指向的就是a这个对象,可在函数体内通过this===a来判断。

3. call、apply、bind方法绑定this

var a={
   printA:function(){
    console.log(this); //对象b,因为通过call将this指向b对象
   }
};
var b={
   printB:function(){
    console.log(this);//对象a,因为通过call将this指向a对象
   }
};
a.print.call(b);
b.print.call(a);

说明:call、apply、bind方法才是最好理解的this,将那个对象绑定进去,函数体里面的this就指向哪个对象。顺便简单说说三者的区别:

 call:第一个参数绑定this,后面的参数顺着排,立即调用。

 apply:第一个参数绑定this,后面的参数放在数组内,立即调用。

 bind:第一个参数绑定this,后面的参数顺着排,不立即调用。

4. 构造函数环境

var A = function(name){
this.name = name;
console.log(this)//b这个实例对象,{name:'wxp'};
};
var b = new A('wxp');
console.log(b);//{name:'wxp'};

说明:记住所有的构造函数内的this指向的都是构造函数的实例对象。想要知道为什么,看看下面模拟的new操作符。

//1.创建一个空对象obj;
//2.调用构造函数并将this指向obj;
//3.返回obj;

function imitateNew(sup){
    var obj = {};
    sup.call(obj);//这里通过call把this指向了obj这个对象
    obj.__proto__= sup.prototype;
    return obj;
}

5. 箭头函数

var a={
   print:function(){
    return ()=>{
   console.log(this);//指向a对象
     }
   }
};
a.print()();

说明:箭头函数中的this指的是外层代码块的this,以上案例在print函数作用域内this指向的就是a这个对象。

三、思考

var a={
   print:()=>{
    return ()=>{
   console.log(this);//指向?
     }
   }
};
a.print()();

可以思考一下,以上 this 会输出什么,为什么?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值