JavaScript类中不使用this关键字引用的变量是否指向全局变量?
问题解答:JS类方法未加
this仍可运行的原因 你遇到的运行正常的情况本质是巧合,核心原因和JS的作用域规则、隐式全局变量特性有关:
- 你在do-while循环中给
num1、num2赋值时,没有加let/const/var声明关键字,这会触发JS的隐式全局变量规则:如果给未声明的变量赋值,JS会自动将该变量挂载到全局对象(Node.js环境下为global对象),成为所有作用域都可以访问到的全局变量。 - 类的方法内部直接使用
num1、num2时,由于方法自身作用域、类作用域下都没有声明同名变量,JS会沿着作用域链向上查找,最终找到的就是你在循环中赋值的全局num1、num2,刚好你赋值全局变量的同时也把相同的值传给了类构造函数存在实例属性this.num1、this.num2里,所以看起来结果是对的。
你可以运行下面的测试代码,就能明显看出原有代码的逻辑漏洞:
const read = require('readline-sync') let flag = 1 class operations { constructor(num1, num2) { this.num1 = num1 this.num2 = num2 } addition() { let sum = num1 + num2 console.log("不用this的计算结果:" + num1 + " + " + num2 + " = " + sum) // 输出实例自身存储的属性计算结果做对比 console.log("用this访问实例属性的计算结果:" + this.num1 + " + " + this.num2 + " = " + (this.num1+this.num2)) } } do { console.log("Enter two numbers ") num1 = read.questionInt() num2 = read.questionInt() let opvar = new operations(num1, num2) // 手动修改全局的num1值 num1 = 999 opvar.addition() flag = read.questionInt("Press 1 to continue and 0 to exit ") } while (flag === 1)
运行后你会发现,方法里不用this的计算结果用的是修改后的全局变量999,和实例自身存储的初始值完全不一样,这就说明你原来的代码只是刚好全局变量和实例属性值一致,才看起来运行正常,并不是类方法默认会访问实例属性。
优化建议
- 正确的类实例属性访问必须加
this关键字,明确表示你要访问的是当前实例自身存储的属性,不受外部全局变量的影响,示例如下:
addition() { let sum = this.num1 + this.num2 console.log(`${this.num1} + ${this.num2} = ${sum}`) }
- 所有变量声明都加上
let/const,避免产生意料之外的隐式全局变量,你也可以在代码最顶部加上'use strict'开启严格模式,这种未声明就赋值的情况会直接抛出错误,帮你提前发现这类问题。
内容的提问来源于stack exchange,提问作者anandsr-dev
相关产品推荐
相关产品推荐

