颠覆三观,javascript中的this到底指代的是啥?
发布于 作者:苏南大叔 来源:程序如此灵动~
苏南大叔准备在本文中描述一个普通人不会这么想的谜题,就是非正常的代码用法,但是也没有报错,运算结果也比较出人意料。甚至于在本文中,node环境和浏览器环境下,运算的结果都有很大差别。

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文讨论js/nodejs代码中,this的指向问题。测试环境:win10,chrome@105.0.5195.102,node@16.14.2。
正常的使用方式
this一般会出现在类的方法里面。所以,this正常的使用方法是这样的:
function Person(name){
this.name = name;
this.getName = function(){
console.log(this);
return this.name;
}
}
var p1 = new Person("sunan");
console.log(p1.getName(), p1 instanceof Person); //sunan true或者
class Person2{
constructor(name){
this.name=name;
}
getName(){
console.log(this);
return this.name;
}
}
var p2 = new Person2("苏南大叔");
console.log(p2.getName(), p2 instanceof Person2); //苏南大叔 true非正常使用方式
下面的代码是非正常使用的方式,考察点有两个:1:this指的是谁,2:this.属性究竟指的是谁。
方式一
a="a"
var b="b"
console.log("this",this,this.a,this.b);这种直接就写this.的代码,输出为:
this {} undefined undefined意思是this为{}。
方式二
a = "a"
var b = "b";
(function () {
console.log("function", this.a, this.b, typeof (this));
console.log(this);
if (typeof global !== 'undefined' && global !== null) {
console.log("global", global.a, global.b, typeof (this));
console.log("global?", this === global)
}
if (typeof Window !== 'undefined' && Window !== null) {
console.log("Window", Window.a, Window.b, typeof (this));
console.log("Window?", this === Window)
console.log("window", window.a, window.b, typeof (this));
console.log("window?", this === window)
}
})();
这次把this.移动到function()定义里面了,
- 如果是在
node环境下,运行上述代码的话,this.指代的是global.。而且,对于没有使用var的全局变量a,是可以访问到的。而使用了var的全局变量b,是无法访问到的。 - 如果是在浏览器环境下,运行上述代码的话,
this.指代的是window.。全局变量无论带不带var,都可以被访问到。
| 运行环境 | this. | var |
|---|---|---|
| node@16.14.2 | global. | 有var则注册不到global |
| chrome@105 | window. | 有没有var都可以注册到window |

方式三
a="a"
var b="b"
var c={};
c.fn = function(){
console.log("function",this,this.a,this.b,typeof(this));
};
c.fn();输出:
function { fn: [Function (anonymous)] } undefined undefined object这里的this.是c={}这个变量,而同样的匿名函数在自执行的时候,this.还是global.或者window.。赋值过后,这个this.又发生了变化。因为这个{}内部,确实没有注册a或者b。所以使用this.a或者this.b都得到的是undefined。
相关链接
- https://newsn.net/say/js-var.html
- https://newsn.net/say/js-object-set-get.html
- https://newsn.net/say/js-object-enumerable.html
- https://newsn.net/say/js-object-configurable.html
- https://newsn.net/say/js-object-writable.html
总结
就同一个带var的b变量,在node环境下和chrome下面居然得到的值不同,这个是始料未及的事情。