简体   繁体   中英

nested properties on a class instance

I need to build a structure (i need to do it for jestjs, in order to stub a module) that allows me to access a method in the following way:

// I make an instance of a class
const myTest = new Test()
// I access a method in this way
const result = myTest.prop1.prop2.prop3.getAll()

A basic class would look like

class Test2 {
  constructor(){}

  //getter
  getAll(){
    return 'Salutes'
  }
}

And I can access getAll()

const myTest2 = new Test()
const result = myTest.getAll()
//in this way result contains a string (*salutes*)

So how can I add more properties in the middle? I found something, but in typescript... I need to do it in javascript

Assuming you need exactly the structure you've specified, in Test you'd have to create the object and have any methods you need be arrow functions or bound functions ( if they need to access information from the Test instance; your example didn't so it wouldn't matter whether they had the right this ). For instance:

 class Test { constructor() { this.prop1 = { prop2: { prop3: { getAll: () => { return "Salutes"; }, getAll2() { // Also works return "Salutes"; }, getAll3: function() { // Also works return "Salutes"; } } } } } } const myTest = new Test(); const result = myTest.prop1.prop2.prop3.getAll(); console.log(result); console.log(myTest.prop1.prop2.prop3.getAll2()); console.log(myTest.prop1.prop2.prop3.getAll3());

Example of using information on the Test instance (it's the same except for the constructor parameter and message property):

 class Test { constructor(message) { this.message = message; this.prop1 = { prop2: { prop3: { getAll: () => { // `this` refers to the `Test` instance because // this is an arrow function return this.message; } // `getAll2` and `getAll3` wouldn't work because // they would get `this` based on how they're called // (it would be the `this.prop1.prop2.prop3` object). } } } } } // I make an instance of a class const myTest = new Test("Salutes encore!"); // I access a method in this way const result = myTest.prop1.prop2.prop3.getAll(); console.log(result);

If you want to achieve it without modifying the Test2 class, you can use Proxy class and define custom handler for get method:

 class Test2 { constructor(){} getAll(){ return 'Salutes' } } let instance = new Test2(); const handler = { get: function(target, prop, receiver) { if (['prop1', 'prop2', 'prop3'].includes(prop)) { return receiver; } return Reflect.get(...arguments); } }; const proxy = new Proxy(instance, handler); console.log(proxy.prop1.prop2.prop3.getAll()); console.log(proxy.prop7); console.log(proxy.getAll());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM