从 JS 类中的内部嵌套构造函数原型访问外部 <this> 的最佳方法是什么?

问题描述

我们是否仍然不能使用比 that 这样的古老变量更优雅的方式来访问具有嵌套类的外部 this,尤其是在涉及私有类字段时?

一个简单的演示示例可能是;

class Person{
  #Ofset;
  #H;
  constructor(name){
    var that  = this;
    this.name = name;
    this.#H   = class{
                  constructor(n){
                    that.#Ofset = Math.random();
                    this.age = n + that.#Ofset;
                  };
                  ofset(){return that.#Ofset}; // accessing outer class's private
                };                             // member from the inner class's
  };                                           // prototype
  setAge(n){
    return new this.#H(n);
  }
};

var p = new Person("Joe").setAge(10);

console.log(p.age);     // 10.09289026855164
console.log(p.ofset()); // 0.09289026855163951

在我的场景中,内部类实例应该能够获取和设置外部类私有字段 #Ofset

所以这就像这样工作得很好,但我想知道是否存在更惯用的解决方案。

解决方法

我不知道你对惯用的确切含义,但更简洁、更简单的方法是避免使用类,而是使用对象和行为委托:

var Person = {
    
    Ofset: 0,name: "",age: 0,setName(name) { this.name = name; },getName() { return this.name; },setAge(n) { 
        this.Ofset = Math.random();
        this.age = n + this.Ofset; 
    },getAge() { return this.age; },getOfset() { return this.Ofset; }
    
};

var p = Object.create( Person );

p.setName("Joe");
p.setAge(10);
        
console.log(p.getAge());     // 10.09289026855164
console.log(p.getOfset());   // 0.09289026855163951

如果你不喜欢额外的步骤 setName,你可以组合这些方法:

...
    setData(name,n) { 
        this.setName(name);
        this.setAge(n);
    },getData() { 
        return {
            name: this.name,age: this.age,Ofset: this.Ofset
        };
    }

};

var p = Object.create( Person );
var m = Object.create( Person );

p.setData("Joe",10);
m.setData("Mary",300);
        
console.log(p.getAge());     // 10.09289026855164
console.log(p.getOfset());   // 0.09289026855163951
console.log(m.getData());    //>{name: "Mary",age: 300.67031318594286,Ofset: 0.6703131859428475}