每日读《你不知道的JavaScript(上)》| this基础
挑重点
今天想换个思路写文章。
在介绍 this,或者有幸了解到 this 之前,你想知道关于 this 的什么?
我先列一个自己的 list:
-
this 是什么?
-
怎么理解 this?
-
this 有什么用?
-
this 指向哪里?
-
this 的使用场景?
... ...
带着问题读书and写作,也许会更深刻。
however,今天先打基础。
this 概念
在我之前的理解里,this 是用来关联获取一些对象中的变量的。
(请注意,JavaScript中函数、Object等等一切皆为对象。)
比如:
var name = 'dazzlingwen';
console.log(this.name); // dazzlingwen
但是诶,好像没有想象中那么简单哦。
当 this 放到函数调用中的时候,看起来就不那么容易了。
因为当一个函数被调用时,会创建一个执行上下文。
这个上下文会包含函数在哪里被调用、函数的调用方法、入参等信息。
而 this 就是这个上下文里的其中一个属性,它能够帮助我们方便快捷地引用其他函数或变量。
所以,我们对 this 的理解应该定位为:
this实际上是在函数调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
🔔🔔需要注意的是:
this 是在运行时进行绑定的,而不是编写的时候。
this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
而this 最难理解的点在于,它的指向该如何判断。
this 指向误区
误区说明
想要搞清楚 this 的指向问题,就需要寻找运行时函数在哪里被调用。
有个误区需要先澄清:
this 既不指向函数自身,也不指向函数作用域。
看这个例子:
function foo(num) {
console.log( "foo: " + num );
// 期望记录 foo 被调用的次数
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
console.log(foo.count);
console.log(window.count);
不瞒你说,这里打印出来的foo.count
是0,不是预期中的调用次数。😵💫😵💫
这里的 this 不会指向 foo 函数本身,反而是在全局环境中创建了一个值为 NAN 的 count 变量。
Q1:为什么是在全局中创建 count?
A1:因为在这里 foo 函数是以普通函数的方式调用的,而不是作为对象方法。
Q2:那为什么全局的 count 打印出来的是 NAN?
A2:全局对象上本来并没有定义 count,所以一开始this.count
的值是undefined,然后对 undefined 进行自增操作就会导致其变为 NAN(Not a Number)。
解决方案
想要上述代码达到预期效果,有如下几种方案:
利用作用域
function foo(num) {
console.log( "foo: " + num );
foo.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo( i );
}
}
console.log(foo.count); // 4
直接把this.count
改为foo.count
,利用 foo 标识符替代 this 来引用函数对象。
强制改变 this 指向
function foo(num) {
console.log( "foo: " + num );
this.count++;
}
foo.count = 0;
var i;
for (i=0; i<10; i++) {
if (i > 5) {
foo.call( foo, i );
}
}
console.log(foo.count); // 4
保留 this,但是在调用 foo 的时候改变 this 指向 foo 函数对象。
小结
今天介绍了 this 的基础知识,为明天的内容做铺垫哦,明天会继续深入 this~
本篇文章主要讲述了 this 概念、大家对 this 的误区和解决方案。
晚安啦,明天再见,继续加油!
转载自:https://juejin.cn/post/7366824731955527732