Javascript 递归对象.defineProperty()getters

Javascript 递归对象.defineProperty()getters,javascript,recursion,prototype,Javascript,Recursion,Prototype,我试图递归地将class构造函数参数中的对象值赋值为类的属性。无法理解如何执行递归-大多数情况下都会得到“超过最大调用堆栈大小”和无限循环。 以下是演示: const Locale = function(rules) { for (let prop in rules) { Object.defineProperty(this, prop, { get: function () { console.log('g

我试图递归地将class构造函数参数中的对象值赋值为类的属性。无法理解如何执行递归-大多数情况下都会得到“超过最大调用堆栈大小”和无限循环。 以下是演示:

const Locale = function(rules) {    
    for (let prop in rules) {
        Object.defineProperty(this, prop, {
            get: function () {
                console.log('getter for "%s" called', prop)
                return rules[prop];
            }
        });
    }
}

const rules = {
    a: {
        b: {
            c: 'value'
        }
    }
}

const locale = new Locale(rules);

console.log(locale.a.b.c);
现在,我将获得以下控制台输出:

getter for "a" called
value
getter for "a" called
getter for "b" called
getter for "c" called
value
如何为
规则
对象的每个级别分配一个getter?预期控制台输出:

getter for "a" called
value
getter for "a" called
getter for "b" called
getter for "c" called
value

您需要为
规则
对象的每个嵌套级别创建一个
区域设置
对象:

const Locale = function(rules) {    
    for (let prop in rules) {
        Object.defineProperty(this, prop, {
            get: function () {
                console.log('getter for "%s" called', prop);

                // create new Locale if object, return value if not an object
                if( rules[prop] !== null && typeof rules[prop] === 'object' )
                    return new Locale( rules[prop] );
                else
                    return rules[prop];
            }
        });
    }
}

const rules = {
    a: {
        b: {
            c: 'value'
        }
    }
}

const locale = new Locale(rules);
console.log(locale.a.b.c);

如果只想使用函数而不是类,可以执行以下操作:

var locale = (rules) => {
  if (rules !== null && typeof rules !== 'object') return rules
  return Object.defineProperties({}, Object.keys(rules).reduce((acc, key) => ({
    ...acc,
    [key]: {
      get: () => {
        console.log('getter for "%s" called', key)
        return locale(rules[key])
      }
    }
  }), {}))
}

var l = locale(rules)
console.log('locale', l)
console.log(l.a.b.c)