【问题标题】:javascript - object value only to be worked out when needed / called uponjavascript - 对象值仅在需要/调用时计算
【发布时间】:2018-02-26 21:21:11
【问题描述】:

例如,我有一个对象,其中键的值尚未知道/计算,但是当我第一次调用该键时,它会计算值并用计算值替换计算/函数。关键是该值仅在需要时才计算出来,然后可以再次重复使用,而无需再次计算出来......

这就是我目前所拥有的......

function newobj() {
        this.test=function(){
        this.test=[1,2,3,4]//complex function in real world use
        return this.test
    }
}

a = new newobj()

a.test() //[1,2,3,4]
a.test() //not a function!
a.test //[1,2,3,4]

如您所见,这需要括号来调用,而不是第二次调用,所以这需要知道它是否已经被调用 - 不理想

第 2 版

function newobj() {
        this.test=function(){
        var a=[1,2,3,4]
        this.test=function(){return a}
        return a
    }
}

a = new newobj()

a.test() //[1,2,3,4]
a.test() //[1,2,3,4] 

这似乎不是解决这个问题的正确方法..但也许是?

抱歉,如果这是一个愚蠢的问题,并提前感谢您的帮助

【问题讨论】:

  • 听起来你正在寻找记忆。最好将test 保留为一个函数,但如果该值已被计算,则只需提前退出。然后从函数的外部看,差异是不透明的。
  • 为什么不在test函数中检查属性是否为undefined,如果是则创建并返回,否则直接返回。并且在使用对象时,始终调用该函数。编辑:正如大卫所说
  • @KarlReid 仍然需要使用函数调用语法

标签: javascript variables object


【解决方案1】:

您可以使用getter 的能力覆盖自身以创建一个“惰性”属性,其值仅在第一次访问时计算:

MDN 上有一个good example

get test() {
  delete this.test;
  return this.test = someExpensiveFunctionCall();
}

对该属性的后续访问甚至不使用getter - 它们直接从对象中检索值。

在您的情况下,由于您没有使用通常的 getter 语法,因此您必须修改您的函数:

function newobj() {
    Object.defineProperty(this, 'test', {
        get: function() {
            delete this.test;
            return this.test = someExpensiveFunctionCall();
        },
        configurable: true
    });
}

【讨论】:

  • 您知道是否有办法将 getter 包含在原始新对象函数中 - (在我的示例中为 newobj() )?似乎无法解决..
  • @wawmsey 我会使用Object.defineProperty() - 见编辑
  • 谢谢,这会将属性添加到对象,但似乎无法删除并用计算值替换自身。如果我将 console.log("bla") 放在 get 函数的开头,那么每次都会调用它——这意味着它不会被删除?
  • 查看编辑 - 我认为我的测试已经成功,但您发现它没有正确删除该属性。您必须将configurable: true 添加到属性描述符以允许删除该属性。如果您希望新属性出现在可枚举属性列表中,您可能还需要添加 enumerable: true
【解决方案2】:

我认为您需要的是Module Pattern。你可以这样做

let Module = (function(){
    let test = null;
    return function(){
        if(test == null){
            console.log('initialized test');
            test = [1, 2, 3, 4];
        }
        return test;
    }
})();

let a = new Module();
console.log(a);
console.log(new Module());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2011-10-06
    • 2012-10-03
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多