在ECMAScript成员函数中,能否让标识符优先查找this成员再查全局?
实现无需重复写
this访问成员的方案 可以实现,但不同方案各有优劣,以下是几种常见的处理方式:
1. 解构this到函数作用域(推荐)
在成员函数的开头,把需要用到的成员解构到局部变量/常量中,后续就能直接使用这些名称:
class MyClass { memberC = 'default'; methodB(arg, val) { return `${arg}-${val}`; } myMethod(someInputArg) { // 解构当前实例的成员到局部作用域 const { methodB, memberC } = this; // 直接使用,读取和调用方法都没问题 const result = methodB(someInputArg, memberC); // 注意:如果要修改实例属性,还是需要通过`this`——因为解构的基本类型是值拷贝,直接赋值局部变量不会同步到实例 this.memberA = result; } }
这种方式简单清晰,无性能损耗,还能避免全局变量冲突——局部变量优先级高于全局,完全符合你"先找this作用域再找全局"的需求。
2. 使用with语句(不推荐)
with语句可以临时改变标识符的查找顺序,让代码块内的优先从指定对象(这里是this)查找:
myMethod(someInputArg) { with(this) { memberA = methodB(someInputArg, memberC); } }
但这个方案有严重缺陷:
- JS引擎无法对
with块内的代码做优化,会导致性能下降; - 严格模式(
'use strict')下直接禁止使用with; - 一旦出现和全局变量同名的成员,容易引发难以排查的意外覆盖问题。
所以除非是非常特殊的场景,否则绝对不建议用。
3. 闭包封装私有成员
如果你的成员不需要对外暴露,可以在构造函数里通过闭包把变量和方法封装起来,这样内部方法就能直接访问,完全不用this:
class MyClass { constructor() { // 闭包内的私有变量和方法 const memberC = 'private value'; const methodB = (arg, val) => `${arg}-${val}`; // 对外暴露的方法 this.myMethod = (someInputArg) => { const memberA = methodB(someInputArg, memberC); // 如果需要把结果暴露到实例上,还是得用`this` this.memberA = memberA; }; } }
这种方式适合完全私有成员的场景,但缺点是每个实例都会创建一份方法副本,无法共享原型上的方法,内存开销会更大。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

