This指向问题(很详细)

This指向相关

一:普通函数的this指向

普通函数中this是动态的,当我们调用函数的时候确定的,调用方式的不同决定了this的指向不同,一般指向我们函数的调用者。(谁调用指向谁)

1、普通函数

//1.普通函数
function fn() {
	console.log('普通函数的this' + this);
}
fn();//window   实际上,这里是window.fn();谁调用,this就指向谁

​ 这里的this指向全局对象window

2、对象的方法

//2.对象的方法
var o = {
  sayHi: function () {
      console.log('对象的方法' + this); //object  this指向的是对象 o
  }
}
o.sayHi()

​ 对象中的方法的this指向该方法所属的对象

3、构造函数

//3.构造函数  this指向实例对象ldh  
function Star() {
    Star.prototype.sing = function () { }//原型对象中的this也是指向实例对象
}
var ldh = newStar();

​ 构造函数和原型对象中的方法,它的调用者是实例对象(这里是ldh),因此在构造函数和原型对象中的方法,this都指向实例对象

4、绑定事件函数

//4.绑定事件函数
var btn = document.querySelector('button');
btn.onclick = function () {
  console.log('绑定事件的this' + this); // 指向btn 也是指向函数的调用者
}

​ 绑定事件的函数,同样遵循谁调用,this指向谁的原则,在这里是btn绑定了点击事件,因此这里的this指向函数的调用者btn

5、定时器函数

//5.定时器函数  this指向window 实际上为window. setTimeout(),也是指向函数的调用者
setTimeout(function () {
    console.log('定时器的this' + this);
}, 1000);

​ 定时器函数的调用,实际上是window. setTimeout(),因此定时器函数的this指向window

6、立即执行函数

//6.立即执行函数  this指向window  相当于普通函数,只是不需要手动调用
(function () {
    console.log('立即执行函数的this' + this);
})();

​ 立即执行函数相当于第一条普通函数,只是它不需要手动调用,因此它的this也指向window。

普通函数总结:

调用方式this指向
普通函数调用window
构造函数调用实例对象
对象方法调用该方法所属对象
事件绑定方法绑定事件的对象
定时器函数window
立即执行函数window

二:箭头函数中的this指向

箭头函数的this指向是静态的,当箭头函数定义的时候,箭头函数的this指向就已经确定了,箭头函数的this指向跟箭头函数所在作用域的this指向一致

1、箭头函数定义在函数中

<script>
    function fn() {
        return () => {
            console.log(this);
        }
	}
    let test = fn()
    test()//window
</script>

​ 箭头函数定义在fn函数作用域内,则箭头函数的this与所在作用域的this指向一致,而普通函数的this指向全局window对象,则该箭头函数也指向window

再次验证:

<script>
    function fn() {
        return () => {
            console.log(this);
        }
	}
    let obj = {
        name: '箭头函数的指向'
    }
	let test = fn.call(obj)
	test()//打印出obj对象
</script>

​ 当执行fn函数的时候,通过call方法修改fn的this指向,则箭头函数的this也跟着改变,意思就是 箭头函数定义在fn函数作用域内,则箭头函数的this与所在作用域的this指向一致

2、箭头函数定义在对象中

<script>
    let obj = {
        name: 'cirrod',
        play: () => {
            console.log(this);
        }
    }
	console.log(obj.play()); //window全局对象
</script>

​ play箭头函数定义在对象中,而在js中只有全局作用域,函数作用域,块级作用域,没有对象作用域,所以相当于箭头函数定义在全局作用域中,箭头函数的this与所在作用域的this指向一致,所以this指向全局对象window

3、箭头函数定义在对象的方法中

<script>
let obj = {
    name: 'cirrod',
    fn: function() {
        return {
            play: () => {
                console.log(this);
            }
        }
	}
}
let obj1 = obj.fn();
console.log(obj1.play());//obj这个对象
</script>

​ 箭头函数定义在fn函数的返回对象中,而对象没有作用域,则向上一层查找fn函数,相当于箭头函数定义在fn函数的作用域内,fn函数的this指向自己所属的对象obj,箭头函数的this与所在作用域的this指向一致,所以箭头函数的this指向为obj

4、箭头函数定义在定时器中

  • 定时器在全局作用域中
<script>
    setTimeout(() => {
        console.log(this); // window
    }, 100)
</script>

箭头函数定义在定时器的参数上,定时器的参数没有作用域,向外一级是全局作用域,相当于箭头函数定义在全局作用域,箭头函数的this与所在作用域的this指向一致,所以箭头函数的this指向为window

  • 定时器在函数作用域
<script>
    function Person(name) {
        this.name = name
        setTimeout(() => {
            console.log(this); // cirrod这个实例对象
        }, 100)
    }
    const cirrod = new Person('黄某某')
</script>

​ 箭头函数定义在定时器的参数上,定时器的参数没有作用域,向外一级是构造函数的作用域,相当于箭头函数定义在构造函数的作用域,而构造函数的this指向实例对象,箭头函数的this与所在作用域的this指向一致,所以箭头函数的this指向为构造函数的实例对象cirrod

三、总结:

  1. 普通函数中this是动态的,当我们调用函数的时候确定的,调用方式的不同决定了this的指向不同,一般指向我们函数的调用者。(谁调用指向谁)

  2. 箭头函数的this指向是静态的,当箭头函数定义的时候,箭头函数的this指向就已经确定了,箭头函数的this指向跟箭头函数所在作用域的this指向一致

四、应用场景:

  1. 箭头函数(静态)适合与this无关的回调,定时器,数组的方法的回调等
  2. 普通函数(动态)适合与this有关的回调,事件回调,对象方法等

ps:总结自某大佬文章(找不到原文了),有修改,侵权删

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值