--外功篇-《JavaScript那些事》-01-理解This指向--

--外功篇-《JavaScript那些事》-01-理解This指向--

功法小传

近日的小虾米,在研习JavaScript招式的过程中,博采众长,勤奋练习,翻阅古籍。
终了然JavaScript招式中,容易引人走火入魔的变数之一——this指向!
虽不敢说完全了然,但其基本理解,心中有数。
对日后行走江湖,多有裨益。
于是,匆匆记下,以备后事之需:

内容正传

JavaScript的this指向问题:
在我们使用JavaScript操作dom时,经常会使用this来引用当前对象。但有时候,往往预料之中的指向却出现个指向错误的问题。
近日,小虾米翻阅了《你不知道的JavaScript》这本书,对其中的this讲解做一个总结和笔记吧。

调用栈

首先需要明白,JavaScript的调用栈的概念。

function three() {
	console.log("three has done!")
}

function two() {
	three();
	console.log("two has done!")
}

function one() {
	two();
	console.log("one has done!")
}

one();
//输出:
// three has done!
// two has done!
// one has done!

在这个代码片段中,我们通过one进行了one->two->three的调用。
由输出可以知道,先进入调用栈的函数最后执行。

this的执行方式

this并不是在函数声明时执行的,而是在函数运行中才执行。

因此,this的指向就与this所处的函数以及函数的状态有关。

this指向的判断

上文中提到“this所处的函数以及函数的状态”,就是传说中的“上下文”。

这么解释起来还是有些抽象。

举个代码例子:
1.

var val = 2;
function a() {
	console.log(this.val);
}
a();
//输出:
// undefined

这个代码片段中的this指向的是全局,因为a函数所处于全局环境中;
2.

function a() {
	console.log(this.val);
}

var obj = {
	val: 1,
	a: a
}
obj.a();
// 输出: 
// 1

这个代码片段中的this指向的是obj,因为a函数所处于obj对象的环境中;

这里,我们就已经解决完一般函数中的this指向问题了。

但要注意,在连续对象嵌套中(如:obj1().obj2().a()),this只会指向他调用栈的前一位对象(例子中只会指向obj2)

PS:有人会将“上下文”理解为this作用时其所处的对象作用域中。这种理解在大部分情况下是这样,但在JavaScript底层的运行过程中并不是如此。

有关this的隐式绑定

this绑定中,还存在一下代码片段的问题:

obj = {
	val: 1,
	a: function() {
		console.log(this.val);
	}
}

function fnc(fn) {
	fn();
}
fnc(obj.a);
// 输出:
// undefined

看到这里肯定会疑惑,a明明是所处于对象obj中的,为什么输出的是undefined这个全局环境才有的结果呢?

记得this的执行原理嘛?this是在代码运行时进行指向。

fnc在执行时,是将obj中的a函数,作为fnc的形参传入fnc中,因此,this的指向与fnc所处环境有关,而与obj无关了。

这就是this的隐式绑定。

关于new绑定和硬绑定

在JavaScript中,我们经常使用new来进行构造函数的实例化,这个过程也是创建了对象,其实例化对象的this指向与之前所讲的对象中的this指向没什么区别

关于硬绑定,是我们使用call、apply、bind进行this强制指向传入对象的方法,来达成我们需要this指向特定对象的目的。

补充:

  1. 关于this指向的一些案例补充

PS:记录至此,若日后还有补充,则另开篇再记录~

posted @ 2020-09-16 13:25  小虾米在code江湖  阅读(135)  评论(0编辑  收藏  举报