Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何对javascript对象上的字段进行惰性求值?_Javascript_Lazy Evaluation - Fatal编程技术网

如何对javascript对象上的字段进行惰性求值?

如何对javascript对象上的字段进行惰性求值?,javascript,lazy-evaluation,Javascript,Lazy Evaluation,我想知道是否有可能采取以下措施: var obj = { counter: (function(){ if(!this.val){ this.val = 0; } this.val += 1; return this.val; })(); }; console.log(obj.counter); //should output 1 console.log(obj.cou

我想知道是否有可能采取以下措施:

var obj = {
   counter: (function(){
                if(!this.val){ this.val = 0; }
                this.val += 1;
                return this.val;
            })();
};

console.log(obj.counter); //should output 1
console.log(obj.counter); //should output 2
console.log(obj.counter); //should output 3
...
有没有一种方法可以从这样的对象中获取字段,使其在每次访问函数时都重新计算该函数?

您可以使用getter:

var obj = {};
Object.defineProperty(obj,"counter",{
    get: function() {
        this.val = this.val || 0;
        this.val++;
        return this.val;
    }
});

console.log(obj.counter); // 1
console.log(obj.counter); // 2
console.log(obj.counter); // 3
obj = Object.create({}, {
    counter: {
        get: function() {
            return this.val = (this.val || 0) + 1;
        }
    }
})
如果您的目标平台支持,这是可能的:

var obj = Proxy.create({
    get: function(target, value) {
        if(value == 'counter')
            return this.val = (this.val || 0) + 1;
    }
});

console.log(obj.counter); //should output 1
console.log(obj.counter); //should output 2
console.log(obj.counter); //should output 3
另一个选择是getter:

var obj = {};
Object.defineProperty(obj,"counter",{
    get: function() {
        this.val = this.val || 0;
        this.val++;
        return this.val;
    }
});

console.log(obj.counter); // 1
console.log(obj.counter); // 2
console.log(obj.counter); // 3
obj = Object.create({}, {
    counter: {
        get: function() {
            return this.val = (this.val || 0) + 1;
        }
    }
})
对象的
值(这不适用于
控制台.log
,但适用于算术):


使用
代理
类以及用于属性评估的评估要求的用例

/*https://github.com/hack2root/lazyeval */
让lazy=(eval)=>((数据)=>新代理(数据、{
设置(对象、键、值){
obj[key]=val;
评估(obj);
}
}))({});
// 1. 安排
设a=1;
设b=2;
让c;
// 2. 表演
设func=lazy((f)=>{
如果(f.a&&f.b){
c=f.a+f.b
}
});
func.a=a;
函数b=b;
// 3. 断言
控制台日志(“c是”,c);
让lazy_require=(请求)=>(评估)=>((数据)=>新代理(数据、{
设置(对象、键、值){
obj[key]=val;
如果(要求(obj)){
评估(obj);
}
}
}))({});
// 1. 安排
设a_f=1;
设b_f=2;
让c_f;
// 2. 表演
让func_require=lazy_require((f)=>f.a和f.b);
让lazy_func=func_请求((f)=>{
c_f=f.a+f.b
});
懒惰函数a=a\u f;
懒惰函数b=b\u f;
// 3. 断言
console.log('c_f is',c_f);
让lazy\u require\u data=(requure)=>(eval)=>(data)=>新代理(data{
设置(对象、键、值){
obj[key]=val;
如果(要求(obj)){
评估(obj);
}
}
});
// 1. 安排
设a_data=1;
设b_数据=2;
让c_数据;
// 2. 表演
设func_require_data=lazy_require_data((f)=>f.a和f.b);
设func_data=func_require_data((f)=>{
c_数据=f.a+f.b
});
设func_json=func_数据({
答:a_数据,
b:b_数据
});
func_json.a=a;
func_json.b=b;
// 3. 断言

日志('c_数据为',c_数据)为什么不使用函数而不是字段计数器被定义为IIFE,因此您对
的引用将丢失到IIFE本身。因此,每次调用
obj.counter
this.val
都是未定义的,因此设置为0,然后设置为1@ksven在回答代码上击败了我,所以我作为一个评论发布。好吧,我可以把实际的计数变量放在其他地方,并且仍然得到自动递增吗?这很好,我不知道它存在。谢谢