我堆积了类似的问题并编写了以下代码:
const dynamicFunc = (input) => {
const handler = {
get: (obj, prop) => {
// edge case when .toString() is calling for dynamic prop - just return any string
if (typeof prop === 'symbol') {
return () => "custom_dynamic_str";
}
const isPropExist = typeof obj[prop] !== 'undefined';
if (isPropExist) {
const val = obj[prop];
// if null or undefined was set
if (val == null || typeof val === 'undefined') {
return val;
}
// if value was created not by this method - return value
if (!val.__isDynamic) {
return val;
}
return dynamicFunc(val);
}
obj[prop] = () => dynamicFunc({});
obj[prop].__isDynamic = true;
return dynamicFunc(obj[prop]);
},
set(target, prop, value) {
// if our custom function was set to dynamic
if (typeof value === 'function') {
// wrap it to unwrap in get
target[prop] =
{
__isSetAsFunction: true,
func: value
};
}
else {
target[prop] = value;
}
return true;
},
apply: function (target, thisArg, argumentsList) {
return dynamicFunc({});
}
};
let proxy = new Proxy(input, handler);
return proxy;
};
return dynamicFunc(baseObj);
我在这里使用 Proxy 类作为基本解决方案,所以用两个词表示 - 每次您尝试访问某个属性时,如果它不存在,它就会创建该属性。是时候编辑了,因为我遇到了很多问题,需要解决它们,所以:)
样本:
let ob = dynamic();
ob.test1.test2.test3('hello from Belarus!','qwerty').test5.t('test');
//we could assign properties on the fly :
ob.myProp.pyProp2 = 2;
console.log(ob.myProp.pyProp2) // "1" will be outputed
// some tests using chai and chai-spies:
dynamic().genericProperties.anyFunc().myprop.test();
let obj = dynamic({ predefinedObjValue: 3 });
obj.prop1.prop2.test = 1;
obj.prop1.prop3.test = 2;
obj.prop2.myfunc = () => { };
expect(obj.prop1.prop2.test).to.be.equal(1);
expect(obj.prop1.prop3.test).to.be.equal(2);
expect(obj.predefinedObjValue).to.be.equal(3);
const myFuncSpy = chai.spy.on(obj.prop2, 'myfunc');
obj.prop2.myfunc();
expect(myFuncSpy).to.have.been.called();
它也不会导致任何错误,您可以定义自己的基础对象并且它不会被覆盖:
let ob = dynamic({mycustomProp : 1});
ob.test1.test2.test3('asdasd','tt').test5.t('test'); //without error
console.log(ob.mycustomProp) // "1" will be outputed
工作样本:https ://codesandbox.io/s/craky-liskov-myf65