是否有可能在javascript中“返回一个getter”

时间:2012-01-12 04:18:14

标签: javascript

我想做这样的事情:

function x(){
    var o = {};
    o.__defineGetter__('y', function(){
        return new Date();
    });

    return o.y;
}

var z = x();
console.log(z);
//Wait 1 second
console.log(z); //Date should be one second past the last printing

当然,这不起作用,因为o.y在返回时会被评估。我正在寻找一种方法来返回一个充当getter的变量。下面的例子让我希望这样的事情是可能的:

function x(context){
    //Bind the getter to the passed in scope
    context.__defineGetter__('y', function(){
        return new Date();
    });
}

x(this);
console.log(y);
//Wait 1 second
console.log(y); //Date is one second past last printing

有没有人试过做这样的事情?

是的,我熟悉使用不同语法对类似行为进行建模的其他方法。我只是希望这种特殊语法适用于特殊情况。

谢谢,

克里斯

2 个答案:

答案 0 :(得分:2)

答案是否定的,你不能为一个变量赋值,这个变量会使变量像变量一样被访问时就像是一个函数。正如您在问题中指出的那样,您最接近的是定义具有getter函数的属性。您无法创建按您描述的方式工作的函数的局部变量。

但是,您可以定义一个函数,该函数使用getter函数(或者更确切地说,是全局对象上的属性)定义全局属性,并使其看起来像您所做的那样。例如,在ES5中,以下内容将创建一个全局变量y,其行为与您描述的一样。

function x(n) { 
    Object.defineProperty(this, n, { 
        get: function() { 
            return new Date(); 
        }
    }); 
}

x('y')

请注意,这仅适用于非严格模式。在严格模式下,this的值为undefined

为什么你会希望变量能够像我无法理解的那样行动。

答案 1 :(得分:1)

这里的问题是,当您在第一个函数中返回o.y时,您没有返回getter方法,而是返回通过调用getter方法返回的Date对象。然后,您将该Date对象分配给z,因此每次console.log(z)时,您都会记录该Date对象,而不是再次调用该函数。

在第二个例子中,当你使用console.log(y)时,你实际上每次都在调用该函数。

一个可能的解决方案,虽然可能不是你想要做的,但是让第一个例子中的getter返回一个函数。然后它会工作。

function x(){
    var o = {};
    o.__defineGetter__('y', function(){
        return function() {
            return new Date();
        }
    });

    return o.y;
}

var z = x();

console.log(z());
//Wait 1 second

setTimeout( function() {
    console.log(z()); //Date is one second past last printing
}, 1000)

Getter方法在Javascript中是一种特殊情况,因为它们在最后没有通常()的情况下调用函数,我想这可能会令人困惑,因为通常你会期望o.y返回一个函数而不是调用函数。