Javascriptのクラス定義


###Object.definePropertyメソッドによるアクセサーメソッドの実装
Object.defineProperty(obj, prop, desc)
obj:プロパティを定義するオブジェクト
prop:プロパティ名
desc:プロパティの構成情報
![スクリーンショット 2017-08-26 12.10.29.png](https://qiita-image-store.s3.amazonaws.com/0/39073/a8e7bd6f-1af5-2edd-8fb2-1dbfdc06146d.png "スクリーンショット 2017-08-26 12.10.29.png")

```javascript
function Triangle() {
// フライヘート変数を宣言
var _base;
var _height;
// baseフロハティを定義
  Object.defineProperty(
    this,
    'base',
    {
      get: function() {
        return _base;
      },
      set: function(base) {
        if(typeof base === 'number' && base > 0) {
          _base = base;
        }
      }
    }
  );
// heightフロハティを定義
  Object.defineProperty(
    this,
    'height',
    {
      get: function() {
        return _height;
      },
      set: function(height) {
        if(typeof height === 'number' && height > 0) {
          _height = height;
        }
      }
    }
  );
};
Triangle.prototype.getArea = function() {
  return this.base * this.height / 2;
};
var t = new Triangle();
t.base = 10;
t.height = 2;
console.log('三角形の底辺:' + t.base);
console.log('三角形の高さ:' + t.height);
```

複数形の場合はObject.definePropertiesを使う

```javascript
function Triangle() {
// フライヘート変数を宣言
var _base;
var _height;
// baseフロハティを定義
  Object.defineProperties(this, {
    'base': {
      get: function() {
        return _base;
      },
      set: function(base) {
        if(typeof base === 'number' && base > 0) {
          _base = base;
        }
      }
    },
    'height': {
      get: function() {
        return _height;
      },
      set: function(height) {
        if(typeof height === 'number' && height > 0) {
          _height = height;
        }
      }
    }
  });
}
Triangle.prototype.getArea = function() {
  return this.base * this.height / 2;
};
var t = new Triangle();
t.base = 10;
t.height = 2;
console.log('三角形の底辺:' + t.base);
console.log('三角形の高さ:' + t.height);
```

###名前空間の作成
名前空間を定義するには、(先述したように)ただ単に「空のオブジェクトを生成する」だけです。ここではで Wings 名前空間を定義しています。

```javascript
var Wings = Wings || {};
 Wings.Member = function(firstName, lastName){
   this.firstName = firstName;
   this.lastName = lastName;
};
 Wings.Member.prototype = {
   getName : function() {
     return this.lastName + ' ' + this.firstName;
   }
};
var mem = new Wings.Member('祥寛', '山田');
console.log(mem.getName());
```

###ES2015のオブジェクト指向構文
Getter, Setter, staticメソッド

```javascript
class Member {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getName() {
    return this.lastName + this.firstName;
  }
  get firstName(){
    return this._firstName
  }
  set firstName(value){
    this._firstName = value;
  }

  static echo_name(name){
    console.log('hello:' + name)
  }
}

let m = new Member('太郎', '山田');
console.log(m.getName());
console.log(m.firstName);
console.log(Member.echo_name('mei'));//Staticメソッド
console.log(m.echo_name('mei'));//Error
```

継承

```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }

  bark() {
    return this.name + "が吠えています"
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name)
  }
}

d = new Dog('犬');
d.bark()
d.constructor === Animal; //false
d.constructor === Dog; //true
```

Prototype継承の時とconstructorの結果が違うことに注意