在 JavaScript 里面, this 是一个特殊的对象, 它不像其他编程语言那样, 是存储在实例中的值, 直接指向此实例.
而是作为一个单独的指针, 在不同的情况之下, 指向不同的位置, 这也是为什么我们会将它搞混的原因.
下面我们来看下, 它在不同情况下分别是怎样一种形态
1. 在全局作用域时:
这个是最好理解的, 即在全局作用域下 this 指向 Windows, 也就是在全局作用域下, this 与 Windows 是等价的:
console.log(this === Windows); //true
另外, 由于在此时, this 等价于 Windows, 所以我们在全局作用域声明的变量也会指向 this:
- var x = 1;
- console.log(this.x);//1
- console.log(Windows.x);//1
当然, 我们还有另一种声明变量的方法:
- x = 0;
- function setNum(){
- x = 1;
- };
- console.log(this.x);//0
- setNum();
- console.log(this.x);//1
当声明变量时不使用 var 或者 let 的话 此时相当于给全局的 this 添加或者改变属性值
看起来还是很简单的, 不就是个等价于 Windows 的对象么.
当然, 如果仅仅是这样, this 或许根本就没有存在的必要了.
而 this 最让人头疼的部分就是它在不同的作用域下, 它的形态也是截然不同的
2. 当在函数中时:
到这里时, this 的陷阱已经渐渐显露出来了
这里为什么说是当在函数中而不是局部作用域时, 要讲这个, 首先我们要清楚 function 是什么
在 JavaScript 中, function 作为 JS 中的一个特殊对象: 函数, 是有着不同的形态的
我们通常看到的:
- function set(){
- var x = 0;
- };
在这一形态下, 其内部的 this 是与全局作用域时一样, 直接指向 Windows, 所以其形态 依然等价于 Windows.
- var x = 0;
- function num(){
- this.x = 1;
- }
- console.log(this.x);//0
- num();
- console.log(this.x);//1
- // 欢迎加入全栈开发交流群一起学习交流: 864305860
这里就是经常容易犯得错误, 很多人觉得, 当 this 已经在一个 function 之中时, 其目前所处位置为当前的局部作用域, 所以目前指向的应该是此函数
但是, 如果你将这个函数实例化 (new) 之后, 此函数将生成一个全新的环境, 此时在此实例中的 this 也会随之发生变化, 它将指向所在实例.
- num = "0";
- function setThis(){
- this.num = "1";
- }
- console.log(this.num);//"0"
- new setThis();
- console.log(this.num);//"0"
- console.log(new setThis().num);//1
这是因为, 当实例化之后, 此函数变成了一个实例对象, 而其内部的 this 也自然而然的指向了此实例对象, 如同一开始的 this 是指向 Windows 的对象一样指向了它所在的实例
另外, 在我们写 JavaScript 的时候, 我们通常还会有一种调用函数的方法, 即为元素绑定事件, 比如 button.addEventListener('click', fn, false)等, 如果在 fn 里面需要使用到 this 的话, 那么此时 this 指向事件处理元素, 也就是 button
注意: this 作为关键字, 你是无法复写它的.
3. 总结:
1. 在全局作用域中 (所有函数外) 出现的 this, 指全局对象.
在浏览器中就是 Windows 对象.
2. 在函数内部出现的 this, 指什么要看这个 this 所在的函数的被调用方式.
不论这个 this 出现在什么样的函数中, 层次有多深, 结构多复杂, 只要看直接包含它的函数即可. 例如:
(1) 被直接调用时, this 指全局对象 Windows.
func();
(2) 被作为构造函数调用时, this 指当前正在构建的对象.
new func();
(3) 被作为某个对象 A 的方法调用时, this 指方法所属的对象 A.
A.func();
(4) 使用函数的 apply 或 call 方法调用时, this 指第一个参数 B.
- func.apply(B, [m, n, ...]);
- func.call(B, m, n, ...);
来源: http://www.qdfuns.com/article/51117/063eaf88f9883547e91fe5f04ef0425b.html