javaScript-深入了解this

2021-06-22·3min
type
Post
summary
status
Published
category
tags
slug
date
Jun 22, 2021
password
icon
📌
首先要明白在执行上下文的准备阶段,会做三件事,分别是:
  1. 创建变量对象
  1. 建立作用域链
  1. 确定this指向
所以this的指向,是在函数调用时才确定的,并且在整个调用过程中,this指向不可改变。

全局上下文中的this

全局上下文中的this指向全局对象,记住这一点就好。

函数上下文中的this

在开头我们就已经得出结论,函数上下文中的this,是在函数被调用时才确定的。
也就是说,函数中的this指向它的调用者。
如果函数作为一个对象的方法被调用,那么this就指向这个对象。
如果函数单独调用,在非严格模式下,this指向全局对象。严格模式下,this为undefined。

一些例子

区分函数中this指向的关键,就是明白函数是单独调用,还是作为某个对象的方法被调用。
在很多情况下我们都能够清楚分辨,但当把一个函数的引用赋值给一个对象的属性时,调用这个属性,this指向什么?
虽然foo.getA与getA的引用一致,但是this指向是在函数调用时才被确定,当getA作为foo的属性被调用时,this自然指向foo。

这里将obj的getA方法作为参数传递给active内部进行执行。同样的,这里传递的是引用,相当于将obj.getA方法的引用赋值给了fn函数,fn单独执行,this指向全局对象,所以打印出20。

使用call,apply,bind显式指定this

JS中有几个支持手动指定函数this的指向的api,它们就是call,apply和bind。
  1. call、apply、bind方法接受的第一个参数都是this要指定的对象。如果不传,或者传了null或undefined,则忽略,默认指向全局对象,严格模式下指向undefined。
  1. call和bind接收的是参数列表,而apply接收的参数数组,且bind返回的新函数也可以接收参数。
  1. call和apply会改变函数内this指向并直接执行函数。而bind会返回一个修改了this指向的新函数。
因为apply,call,bind的存在,我们可以灵活的对方法进行借用。
  1. 类数组转换为数组
2.求数组或者对象中的最大值

构造函数和原型方法上的this

要搞清在new一个构造函数的过程中,构造函数中的this指向了谁,就要搞明白new的过程中发生了什么。
  1. 创建一个空对象。
  1. 把构造函数的this指向这个对象。
  1. 执行构造函数中的代码,给这个对象添加属性和方法。
  1. 返回这个对象。
所以,new调用构造函数时,this指向的是这个新创建的实例对象。
而原型方法上的this,就很容易理解了,指向的是调用这个方法的实例本身。

箭头函数的this

箭头函数中的this指向比较特殊,跟其他的函数不同。
箭头函数中的this指向不是在调用函数时决定的,而是由它创建时所处的上下文中的this指向决定。
并且,箭头函数中的this不能通过call,apply,bind来改变。
但可以通过改变所处上下文的this指向,间接改变箭头函数的this指向。

参考链接

> cd ..