Аккуратные альтернативы __defineGetter__? - PullRequest
11 голосов
/ 20 апреля 2011

Геттеры и сеттеры - это красота в VB.Net:

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;
    });
}

Это похоже на тарелку спагеттиразграблен кури.Какие у нас есть более аккуратные альтернативы?

Примечание. Новый код должен получить доступ к значению, используя new Test().Width, а не new Test().Width().

Ответы [ 3 ]

11 голосов
/ 20 апреля 2011

С ES5 вы сможете выполнять:

function Test() {
  var a = 1;

  return {
    get A() { return a; },
    set A(v) { a = v; }
  };
}

Функции получения / установки, конечно, могут делать все, что вы хотите.

9 голосов
/ 20 апреля 2011

Вот чистая (er) альтернатива (также для старых скриптовых движков):

function Test() {
  var a=1;
  return { A: { toString: function(){return a;} } };
}

alert(Test().A); //=> 1

Имейте в виду, вы не можете использовать его для определения частных / статических сложных структур. Вы можете только 'получить' строки или числа (так что неизменяемые переменные) с этим шаблоном. Возможно, шаблон можно улучшить с помощью json.

[ edit ] Используя json, вы также можете создать геттер для объектов:

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
6 голосов
/ 04 марта 2012

В Ecmascript5 «чистый» (и соответствующий стандартам) способ сделать это с помощью defineProperty.

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

Это предполагает, что вы просто хотите увидеть, как определить получатель.Если все, что вы хотите сделать, это сделать экземпляры Test неизменяемыми (это хорошо делать, где вы можете), вы должны использовать freeze для этого:

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