尝试用简单直观的方法,为学编程的朋友提供一种思路。
this,在编程语言里,指代某个引用了“this所在的函数”的内存空间。
在C++、java等语言里,当声明一个类,并实例化一个对象时,this指的是这个对象所在的(复制出来的)内存空间。
![](https://img.haomeiwen.com/i12522178/04eaa8a2cceb961c.png)
所以用this.xx的语法可以引用该内存块内的各种变量。
c++等程序经过编译成机器码后,每个this都有固定的内存块指向,所以this的指向很明确。
而js是一种脚本解释型语言,支持函数式编程,所有函数在执行前,都是以字符串的形式存在的。
![](https://img.haomeiwen.com/i12522178/3497120cdbb7ebcb.png)
除了可以在a1里直接引用
a1.f1();
实例a1里的函数f1的函数内容,还可以通过赋值语句传给其他对象使用(这是非函数式编程语言做不到的)
var k1=a1.f1;
k1();
这时,函数的实际执行内存空间,就变成了k1所在的内存空间。
那么这个空间是哪里呢?
在js里,当某个对象没有显式声明时,都会自动挂载在全局对象window上。
所以上述例子k1();相当于window.k1();函数中的this,指代的就是window了。
![](https://img.haomeiwen.com/i12522178/eb272eb5001d56ef.png)
而当k1有显式声明的所有者时
var owner={};
owner.k1=a1.f1;
owner.k1();
执行时,this所在的内存空间为owner,所以这里this指代的是owner。
PS:这里可以再深究owner所在的内存空间,其实也是window,但是this只会指向最终引用它的那一块内存空间,不会再往上指向。
完整示例如下
var p = 2; //挂载在window上的p=2
var a1 = {
p: 1, //a1里的p=1
f1: function() {
console.log(this.p);
}
}
a1.f1(); //这里输出 1
k1 = a1.f1;
k1(); //这里输出 2
var owner = {};
owner.p = 3; //挂载在owner里的p=3
owner.k1 = a1.f1;
owner.k1(); //这里输出 3
几种特殊情况
-
使用严格模式时(在代码首行加上'use strict'),只有直接引用时this会生效,通过赋值给其他对象使用的话,this会报错。
-
箭头函数里的this,会自动绑定定义时所在的内存空间,不会发生指向变化。
-
闭包所在的一阶函数内的this,因为闭包会自动挂载在window下,这时候this指代window。
-
js支持在函数内定义另一个函数,这时候定义出来的函数如果没有显式执行,也会自动挂载在window上。
function a(){
function b(){
this....
}
return b(); //b自动挂载在window上执行,相当于window.b()
}
a(); //这时函数b里的this指代window
网友评论