this的指向以及改变this指向的方法

很多小伙伴会被this的指向问题弄得焦头烂额,或者这次记住了,下次别人一问,又答不上来,那么这次就让我们彻底捋清楚

首先,要清楚一点,

this的指向在函数声明的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁

  1. this永远指向的是最后调用它的对象,这里强调最后
  2. window是浏览器中js中的全局对象,globalwindow是nodejs的全局对象,我们创建的变量实际上是给全局对象添加属性
  3. 非严格模式下,例如user()其实等价于window.user(),所以默认指向是window,而严格模式下,this不会有默认指向,因而是undefined
  4. 箭头函数 没有自己的this,只会从自己的作用域链的上一层继承this

下面我们通过代码进一步了解(非严格模式下)

function User(){
	var name = 'henry';
	console.log(this)//打印出了window,因为user()其实就是window.user()
	console.log(this.name)//undefined
}
User()
var user = {
    name:"henry",
    getName:function(){
        console.log(this.name);  //henry,因为调用函数getName的是user
    }
}
user.getName();
var user = {
    age:26,
    names:{
        chinese:'楠',
        english:'henry'
        getEnglishName:function(){
            console.log(this.english); //henry,因为调用的对象是names
            console.log(this.age)//undefined
        }
    }
}
user.names.getEnglishName();
var user = {
    age:26,
    names:{
        chinese:'楠',
        english:'henry'
        getEnglishName:function(){
            console.log(this); //window,因为最后调用的对象是window
            console.log(this.english)//undefined
        }
    }
}
var getEnglishName = user.names.getEnglishName;//创建的变量实际上是给全局对象(window)添加属性
getEnglishName();//等价于window.getEnglishName()

上面的三个例子说明:this指向最后调用函数的那个对象

下面我们继续看

构造函数版this

function User(name){
	this.name = name;
}
const user = new User('henry')
console.log(user.name) //henry

new关键字就是创建一个对象实例,并将this指向这个实例对象

但还有种情况比较特殊,当this碰到return时

function User1()  
{  
    this.index = 1;  
    return {};  
}
function User2()  
{  
    this.index = 2;  
    return function(){};  
}
function User3()  
{  
    this.index = 3;  
    return [];  
}
var user1 = new User1();  
console.log(user1.index); //undefined
var user2 = new User2();  
console.log(user2.index); //undefined
var user3 = new User3();  
console.log(user3.index); //undefined
function User1()  
{  
    this.index = 1;  
    return 'user1';  
}
function User2()  
{  
    this.index = 2;  
    return undefined;  
}
function User3()  
{  
    this.index = 3;  
    return null;  
}
function User4()  
{  
    this.index = 4;  
    return true;  
}
function User5()  
{  
    this.index = 5;  
    return 1000;  
}
var user1 = new User1();  
console.log(user1.index); //1
var user2 = new User2();  
console.log(user2.index); //2
var user3 = new User3();  
console.log(user3.index); //3
var user4 = new User4();  
console.log(user4.index); //4
var user5 = new User5();  
console.log(user5.index); //5

由上面的例子可以看出,如果返回值是一个引用类型时,那么this指向的就是那个返回的对象,如果返回值不是一个引用类型时,那么this还是指向函数的实例


* 改变this指向的三种方法

说了那么多,那this指向是否有办法改变,当然有,分别是callapply,以及 bind

先看一个例子

function Person(sex, height){
    console.log(sex + "," + height);//boy,180
    console.log(this);//window对象
}
Person("boy",180)

然后我们分别用 callapply 来改变this指向

1.call() 方法

var user = {
    name:"henry",
    age:26
}
function Person(sex, height){
    console.log(sex + "," + height);//boy,180
    console.log(this);//user对象
    console.log(this.name);//henry
    console.log(this.age);//26
}
Person.call(user,"boy",180);

2.apply() 方法


var user = {
    name:"henry",
    age:26
}
function Person(sex, height){
    console.log(sex + "," + height);//boy,180
    console.log(this);//user对象
    console.log(this.name);//henry
    console.log(this.age);//26
}
Person.apply(user,["boy",180]);

接着我们来看看bind改变this指向的例子

var App = document.getElementById("app");
App.onclick = function(){
	this.id='app'
    setTimeout(function(){
        console.log(this);//window,相当于window.setTimeout
        console.log(this.id)//undefined
    },1000)
}

那么怎么把this改成指向div呢?


var App = document.getElementById("app");
App.onclick = function(){
	this.id='app'
    setTimeout(function(){
        console.log(this);//this指向了App
        console.log(this.id)//app
    }.bind(this),1000)
}

这里需要注意,箭头函数没有this,不能当构造函数new,当然也无法用apply,call,bind等方法改变this指向,具体可以看 MDN

以上就是我对this的总结,看完这个之后如果对new感兴趣的话,可以接着看下一篇 了解一下new的过程发生了什么,以便更进一步了解上面new过程的this指向

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值