JavaScript全局变量访问问题:普通与箭头函数作用域差异解惑
嘿,我来帮你把这个问题掰扯清楚,先从你的代码输出说起~
先唠唠你的代码为啥会输出
undefined 和 20 先理一遍代码的执行顺序你就懂了:
- 你创建
d2 = new Data2()的时候,没给Data2传参数——而Data2继承了Data1的构造函数,构造函数里的m1没收到值,所以d2实例的m1初始就是undefined。 - 调用
d2.func1()时:func1是普通类方法,它的this是调用的时候才绑定的,这里就是指向d2本身,所以console.log(this.m1)自然打印undefined;- 之后你把
this.m1改成20,d2的m1就变成20了。
- 再调用
d2.func2():func2是箭头函数定义的类属性,箭头函数没有自己的this,它的this是定义的时候就绑定好的——也就是类实例化时的d2。这时候d2.m1已经被func1改成20了,所以打印20,之后又改成40。
你说普通函数“无法打印全局变量”其实是个小误解——这里的m1根本不是全局变量,是d2实例自己的属性。普通函数func1里的this是正确指向d2的,只是初始值是undefined而已~
普通函数和箭头函数的「this绑定/作用域」核心差异
这是JS里绕不开的知识点,我给你拆成好懂的几点:
普通函数的
this:看谁调用它
普通函数的this是“动态绑定”的,完全看调用方式:- 如果是对象调用它(比如
d2.func1()),this就指向这个对象; - 如果直接裸调用(比如
func1()),非严格模式下this指向全局对象(浏览器是window,Node里是global),严格模式下是undefined; - 用
new调用构造函数时,this指向新创建的实例; - 还能通过
call()/apply()/bind()手动改this的指向。
另外普通函数有自己的独立作用域,内部能拿arguments,也能嵌套普通函数(嵌套函数的this同样看调用方式)。
- 如果是对象调用它(比如
箭头函数的
this:跟着定义时的上下文走
箭头函数天生没有自己的this,它的this是从定义时的外层作用域“继承”来的,一旦绑定就再也改不了——哪怕用call()强行传值也没用。
除此之外,箭头函数没有arguments,不能当构造函数用(不能new),也没有prototype属性。它最常用的场景就是需要保留外层this的时候,比如类的属性、回调函数里。
普通函数里怎么访问全局变量?
全局变量本质是挂在全局对象上的(浏览器是window,Node是global,ES6+有个跨环境的globalThis更推荐)。在普通函数里访问全局变量分几种情况:
直接用变量名:如果函数内部没有同名的局部变量“挡住”它,直接写变量名就能拿到全局变量:
const globalMsg = "我是全局的!"; function showMsg() { console.log(globalMsg); // 直接打印全局变量 } showMsg(); // 输出:我是全局的!通过全局对象访问:如果函数内部有同名变量,或者你想明确指定拿全局的,就用
globalThis(跨浏览器/Node都能用):const globalMsg = "我是全局的!"; function showMsg() { const globalMsg = "我是局部的!"; console.log(globalThis.globalMsg); // 明确访问全局变量,输出:我是全局的! } showMsg();类的普通方法里访问全局变量:和上面一样,只要没被实例属性或局部变量遮蔽,直接用变量名就行:
const globalNum = 100; class MyClass { myFunc() { console.log(globalNum); // 直接访问全局变量 } } new MyClass().myFunc(); // 输出:100
内容的提问来源于stack exchange,提问作者hari prasanth
相关产品推荐
相关产品推荐

