__defineGetter__的简洁替代方案

Neat alternatives to __defineGetter__?

本文关键字:方案 简洁 defineGetter      更新时间:2023-09-26

getter和setter在VB中是一个美丽的东西。净:

Get
    Return width
End Get
Set(ByVal value As Integer)
    width = value
End Set

在Javascript中,我们可能会这样做:

function Test() {
    var width = 100;
    this.__defineGetter__("Width", function() {
        return width;
    });
    this.__defineSetter__("Width", function(value){
        width = value;
    });
}

它看起来像一盘意大利面被kuri洗劫。我们有什么更好的选择吗?

注意:新代码应该使用new Test().Width而不是new Test().Width()访问值

使用ES5,您将能够:

function Test() {
  var a = 1;
  return {
    get A() { return a; },
    set A(v) { a = v; }
  };
}

getter/setter函数当然可以做任何你想让它们做的事情。

这里有一个干净的(er)替代方案(也适用于旧的脚本引擎):

function Test() {
  var a=1;
  return { A: { toString: function(){return a;} } };
}
alert(Test().A); //=> 1

注意,你不能用它来定义私有/静态的复杂结构。你只能用这个模式"获取"字符串或数字(所以不可变的变量)。也许该模式可以使用json.

来增强。

[edit]使用json,你也可以这样为对象创建getter:

function Test() {
  var a=1,
  b = {foo:50, bar:100};
  return { 
          A: { toString: function(){return a;} } 
          foobar: { toString: function(){return JSON.stringify(b);}  } 
         };
}
var foobar = JSON.parse(Test().foobar);
alert(foobar.foo); //=> 50

在Ecmascript5中,"干净"(并且符合标准)的方法是使用defineProperty。

function Test() {
    var a = 1;
    Object.defineProperty(this, "A", {get : function() { 
            return a;
        },  
        enumerable : true});
}

这里假设你只是想看看如何定义getter。如果您想要做的只是使Test的实例不可变(在可能的情况下这样做是件好事),那么您应该使用freeze:

function Test() {
    this.a = 1;
    Object.freeze(this);
}