为什么要使用this
在了解this机制之前,我们先来看看为什么要使用this呢?来看这个例子。
const person = {
name: "丁时一",
};
//在使用this之前 需要显式的传入对象
function say(context) {
console.log(context.name);
}
say2(person); //丁时一
在使用this之前,我们需要给say函数显式的传入一个一个上下文对象,随着你的模式越来越复杂,显式的去传递上下文会让你的代码与来越混乱,使用this则不会这样。
function say() {
console.log(this.name);
}
const person = {
name: "丁时一",
};
say.call(person); //丁时一
这里我们使用call函数来显式的改变say的上下文,并且调用。
指向自身
第一种误解:人们很容易把this理解为指向自身(至少从英文的意思上是这样的)。那么我们来看看这一个例子。我们想要用一个变量count来记录函数foo调用了多少次。
function Foo(num) {
console.log("foo", num);
this.count++;
}
Foo.count = 0;
for (let i = 0; i < 5; i++) {
Foo(i);
}
//foo 0
//foo 1
//foo 2
//foo 3
//foo 4
//foo被调用了多少次
console.log(Foo.count); //0 ! 我擦??
结果并不是我们所预期的5,那么为什么呢?
深入的去看的话,其实我们在调用foo函数的时候,无意之间创建了一个全局变量count,它的值为NaN。
console.log(window.count); //NaN 为什么是NaN呢? undefined+1
发现了这个奇怪的结果,那么你一定会接着问:为什么它是全局的?,为什么它的值为NaN?,莫方,我来回答。
来看下一段代码:
this.count = this.count + 1;
console.log(this.count);//NaN
//相当于下面一段代码
var count
count=count+1
console.log(count);//NaN
console.log(undefined+1);//NaN
我们在全局中直接使用,结果也是一样的,并且我们打印undefined+1结果也是NaN,欸,看到这里你是不是明白了什么呢?在上一个例子中调用this.count++的时候,就是给全局声明了一个变量但并未初始化,如果看过var,let,const那篇文章的应该就知道了,没有初始化就给值undefined,然后undefined++就是NaN了,我明白啦!这么说来,那么之前那个例子指向的就是window咯?你可真是个小机灵鬼,打印试试吧!
function Foo(num) {
console.log("foo", num);
console.log(this); //window
}
Foo(1)//foo 1
它的作用域
第二种常见的误解就是this指向函数作用域,这个问题有点复杂,因为在某种情况下它是正确的,但是在其他情况下却是错误的。需要明确的是this.在任何情况下都不指向函数的词法作用域。
思考下面一段代码,它试图(但是没有成功)跨越边界,使用this来隐式引用函数的词法作用域。
function foo() {
var a = 3;
this.bar();
}
function bar() {
console.log(this.a);
}
foo();//undefined 之前是ReferenceError
这段代码中对的错误不只一个,bar函数能调用成功纯属巧合,如果this能指向函数作用域的话,那么打印的this.a应该是3而不是undefined了
this到底是什么
这里简单的总结一下,this的指向与this的位置无关,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
当一个函数频繁的调用时,会创建一个活动对象(AO or GO 有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、含糊的调用方式、传入的参数信息等。this就是这个记录的一个属性,会在函数执行的过程中用到。在下一篇文章中,博主将会分享如何寻找函数调用的位置,从而判断函数在执行过程中会如何绑定this。
本篇文章博主的分享就到这里啦~,有什么建议或者想说的话,可以在评论区留言嗷!