35360


JavaScriptでいろいろコードを試しています。  
ES5で考えています。

プロパティの入出力に対して、  
アクセスメソッドを動かすことはできますか？

C#などではプロパティに対して  
get/setなどのアクセスメソッドを  
記述するのが普通ですが、

JavaScriptでは、プロパティという言葉自体が  
公開されたフィールド変数、の意味で使われています。

なので、たとえば下記のように書くのですが

この時に、getRight() とよびださなければいけないのですが  
かっこわるいというか  
他言語からの移植などの場合にも困るので  
アクセスメソッドは公開せずに  
right プロパティをよみだしたときに  
getRigthが裏で動いている、というようなことが  
実現できないのか、と思っています。

ご存じの方おられましたら、教えてください。  
よろしくおねがいします。

また、ES5は無理そうだとか、  
ES6なら or TypeScriptなら、可能なども  
おしえていただければ、助かります。

[code]

    var common = {};
    (function () {
      var _ = common;
    
      //Rect(top,left,height,width)
      _.Rect = function (top, left, height, width) {
        if (!(this instanceof common.Rect)) {
          return new common.Rect(top, left, height, width);
        }
        this.top = top;
        this.left = left;
        this.height = height;
        this.width = width;
      };
      _.Rect.prototype.getRight = function() {
        return this.left + this.width;
      };
      _.Rect.prototype.getBottom = function() {
        return this.top + this.height;
      };
    
    }());
    
    var rect1 = common.Rect(1,1,1,1);
    というように使う
    
[/code]


CC BY-SA 3.0
2017-06-07T03:32:52.627
35359
2017-06-07T05:38:39.347
21047
question
javascript
JSのプロパティ入出力時にアクセスメソッドを動かしたい


[Object.defineProperty](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
でgetを使うことでできると思います。  
以下例：

[code]

    var common = {};
    (function () {
      var _ = common;
    
      //Rect(top,left,height,width)
      _.Rect = function (top, left, height, width) {
        if (!(this instanceof common.Rect)) {
          return new common.Rect(top, left, height, width);
        }
        this.top = top;
        this.left = left;
        this.height = height;
        this.width = width;
        Object.defineProperty(this, "right", { get: function () { return this.left + this.width; } });
        Object.defineProperty(this, "bottom", { get: this.getBottom });
    
      };
      _.Rect.prototype.getRight = function() {
        return this.left + this.width;
      };
      _.Rect.prototype.getBottom = function() {
        return this.top + this.height;
      };
    
    }());
    
    var rect1 = common.Rect(1,2,3,4);
    console.log(rect1.right);
    console.log(rect1.bottom);
[/code]


CC BY-SA 3.0
2017-06-07T04:15:45.793
35360
2017-06-07T04:45:42.393
2017-06-07T04:45:42.393
5044
5044
35359
answer


BLUEPIXYさんに教えていただいた方法を応用して  
下記コードで、アクセスメソッドをprivateにすることもでき、  
setも作成することができました。

こんなことができると全くしらなかったので、大変勉強になりました。  
知らなかったので検索することもできませんでした。

BLUEPIXYさん、ありがとうございます。

[code]

    _.Rect = function (top, left, height, width) {
      if (!(this instanceof common.Rect)) {
        return new common.Rect(top, left, height, width);
      }
      this.top = top;
      this.left = left;
      this.height = height;
      this.width = width;
    
      var getRight = function() {
        return this.left + this.width;
      };
      var setRight = function(value) {
        this.width = value - this.left;
      };
      var getBottom = function() {
        return this.top + this.height;
      };
    
      Object.defineProperty(this, "right", {
        get: getRight,
        set: setRight
      });
      Object.defineProperty(this, "bottom", {
        get: getBottom 
      });
    };
    
[/code]

※コメント欄では文字数が足りなかったので、  
回答として、コードも含めて投稿しておきます。


CC BY-SA 3.0
2017-06-07T05:38:39.347
35363
2017-06-07T05:38:39.347
21047
35359
answer