Casual Developers Note

エンジニアやデザイナー向けの技術情報・英語学習情報・海外留学情報・海外旅行情報を提供中。世界を旅して人生を楽しもう。

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • お問い合わせ
現在の場所:ホーム / アーカイブclass

2018年10月1日 By KD コメントを書く

JavaScriptによるオブジェクト指向プログラミング(class編)

JavaScriptによるオブジェクト指向プログラミング(class編)

ES6からclassシンタックスシュガーが導入され、JavaScriptでのオブジェクト指向プログラミングが分かりやすくなりました。今回はclassを使用したJavaScriptのオブジェクト指向プログラミングの方法を紹介します。

はじめに

前回Prototypeチェーンを使用したJavaScriptのオブジェクト指向プログラミングを紹介しました。今回はES6で導入されたclassシンタックスシュガーを使用したJavaScriptのオブジェクト指向プログラミングの方法を紹介します。

クラスの定義

まずは、classシンタックスシュガーでクラスを定義してみましょう。

class Component {
  constructor(name, props = {}) {
    this.name = name;
    this.props = props;
  }

  toString() {
    return `name: ${this.name}, props: ${JSON.stringify(this.props)}`;
  }

  static isComponent(obj) {
    return obj instanceof this;
  }
}

const myComponent = new Component('Component', { color: 'blue' });
console.log(myComponent.toString()); // => name: Component, props: {"color":"blue"}
console.log(Component.isComponent(myComponent)); // => true

この例では、toString関数がいわゆるインスタンスメソッドで、isComponent関数がいわゆるクラスメソッドです。

カプセル化とGetter/Setterの定義

2つの方法があります。

WeakMapを使う方法

WeakMapを使って実装してみましょう。

const _name = new WeakMap();
const _props = new WeakMap();
const _capitalize = new WeakMap();

class Component {
  constructor(name, props = {}) {
    _name.set(this, name);
    _props.set(this, props);

    _capitalize.set(this, letter => letter.toUpperCase());
  }

  get name() {
    return _name.get(this);
  }

  get props() {
    return _props.get(this);
  }

  set props(props) {
    _props.set(this, props);
  }

  toString() {
    return `name: ${this.name}, props: ${JSON.stringify(this.props)}`;
  }

  shoutName() {
    console.log(`${_capitalize.get(this)(this.name)}!!`);
  }
}

const myComponent = new Component('Component', { color: 'blue' });
console.log(myComponent.toString()); // => name: Component, props: {"color":"blue"}
myComponent.name = 'Not Changed'; // 変更されない
myComponent.props = { color: 'green' };
console.log(myComponent.toString()); // => name: Component, props: {"color":"green"}
myComponent.shoutName(); // => COMPONENT!!

この例では、nameプロパティはSetterが無いため値を変更できません。一方で、propsプロパティはGetter/Setterが両方あるため、変更も取得もできます。

Symbolを使う方法

Symbolを使って実装しましょう。

const _name = Symbol();
const _props = Symbol();
const _capitalize = Symbol();

class Component {
  constructor(name, props = {}) {
    this[_name] = name;
    this[_props] = props;
  }

  [_capitalize](letter) {
    return letter.toUpperCase();
  }

  get name() {
    return this[_name];
  }

  get props() {
    return this[_props];
  }

  set props(props) {
    this[_props] = props;
  }

  toString() {
    return `name: ${this.name}, props: ${JSON.stringify(this.props)}`;
  }

  shoutName() {
    console.log(`${this[_capitalize](this[_name])}!!`);
  }
}

const myComponent = new Component('Component', { color: 'blue' });
console.log(myComponent.toString()); // => name: Component, props: {"color":"blue"}
myComponent.name = 'Not Changed'; // 変更されない
myComponent.props = { color: 'green' };
console.log(myComponent.toString()); // => name: Component, props: {"color":"green"}
myComponent.shoutName(); // => COMPONENT!!

この例でも先程と同じく、nameプロパティはSetterが無いため値を変更できません。一方で、propsプロパティはGetter/Setterが両方あるため、変更も取得もできます。

継承とポリモーフィズム

継承

extendsを使って実装できます。

const _name = new WeakMap();
const _props = new WeakMap();
const _capitalize = new WeakMap();

class Component {
  constructor(name, props = {}) {
    _name.set(this, name);
    _props.set(this, props);

    _capitalize.set(this, letter => letter.toUpperCase());
  }

  get name() {
    return _name.get(this);
  }

  get props() {
    return _props.get(this);
  }

  set props(props) {
    _props.set(this, props);
  }

  toString() {
    return `name: ${this.name}, props: ${JSON.stringify(this.props)}`;
  }

  shoutName() {
    console.log(`${_capitalize.get(this)(this.name)}!!`);
  }
}

const _children = new WeakMap();

class Welcome extends Component {
  constructor(props, children) {
    super('Welcome', props);
    _children.set(this, children);
  }

  render() {
    return `<h1>${_children.get(this)}</h1>`;
  }
}

const welcome = new Welcome({ color: 'orange' }, 'Welcome to here!');
console.log(welcome.toString()); // => name: Welcome, props: {"color":"orange"}
welcome.shoutName(); // => WELCOME!!
console.log(welcome.render()); // => <h1>Welcome to here!</h1>

ポリモーフィズム

続いて、ポリモーフィズムを実装してみましょう。

const _name = new WeakMap();
const _props = new WeakMap();
const _capitalize = new WeakMap();

class Component {
  constructor(name, props = {}) {
    _name.set(this, name);
    _props.set(this, props);

    _capitalize.set(this, letter => letter.toUpperCase());
  }

  get name() {
    return _name.get(this);
  }

  get props() {
    return _props.get(this);
  }

  set props(props) {
    _props.set(this, props);
  }

  toString() {
    return `name: ${this.name}, props: ${JSON.stringify(this.props)}`;
  }

  shoutName() {
    console.log(`${_capitalize.get(this)(this.name)}!!`);
  }
}

const _children = new WeakMap();

class Title extends Component {
  constructor(props, children) {
    super('Title', props);
    _children.set(this, children);
  }

  render() {
    return `<h1>${_children.get(this)}</h1>`;
  }
}

const _children2 = new WeakMap();

class Paragraph extends Component {
  constructor(props, children) {
    super('Paragraph', props);
    _children2.set(this, children);
  }

  render() {
    return `<p>${_children2.get(this)}</p>`;
  }
}

const title = new Title({ color: 'orange' }, 'What is OOP?');
const paragraph = new Paragraph({ color: 'black' }, 'The OOP means an object oriented programming.');

const components = [title, paragraph];
components.forEach(component => console.log(component.render()));
// => <h1>What is OOP?</h1>
// => <p>The OOP means an object oriented programming.</p>

最後に

いかがでしたか?classシンタックスのおかげでprototypeと比べて簡単かつ直感的にオブジェクト指向プログラミングが実装できるようになりましたね。最近のフロントエンドフレームワークはオブジェクト指向で書く事が多いので、書き方は理解しておきましょう。では。

カテゴリ : 技術 Tips & Tutorials タグ : class, es6, javascript, oop

ブログ更新情報や海外の関連情報などを配信する無料メルマガ

Sponsored Links

About Author

KD

世界を旅し日本を愛するエンジニア。大学でコンピュータサイエンスの楽しさを学び、日本の大手IT企業で働く中で、新しい技術やスケールするビジネスが北米にある事に気づく。世界に挑戦するための最大の壁が英語であったため、フィリピン留学およびカナダ留学を経て英語を上達させた。現在は日本在住でエンジニアとして働きつつ、次の挑戦に備えて世界の動向を注視している。挑戦に終わりはない。このブログでは、エンジニアやデザイナー向けの技術情報から、海外に留学したい人向けの留学情報、海外に興味がある人向けの海外旅行情報など、有益な情報を提供しています。

https://casualdevelopers.com/

最近の投稿

  • 2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年1月13日
  • 今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    2019年11月4日
  • ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    2019年10月30日
  • BashからZshに移行する方法(Mac編)

    BashからZshに移行する方法(Mac編)

    2019年10月21日
  • Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    2019年9月30日

カテゴリ

  • 技術 Tips & Tutorials (100)
  • 技術塾 (6)
  • ライフハック (26)
  • 海外留学 (12)
  • 英語学習 (3)
  • コラム (6)

アーカイブ

最高の学習のために

人気記事ランキング

  • MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
    MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
  • Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
    Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
  • SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
    SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
  • Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
    Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
  • [tips][perl] Perlで文字コードをいい感じに処理する方法
    [tips][perl] Perlで文字コードをいい感じに処理する方法
  • 爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
    爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
  • FacebookログインのJavascriptのSDKをサクッと試す方法
    FacebookログインのJavascriptのSDKをサクッと試す方法
  • PythonでWebスクレイピング入門(Scrapy+Selenium編)
    PythonでWebスクレイピング入門(Scrapy+Selenium編)
  • Amazon EC2インスタンスにSSHできなくなった時の対処法
    Amazon EC2インスタンスにSSHできなくなった時の対処法
  • [tips][bat] バッチで明日の日付を計算する。
    [tips][bat] バッチで明日の日付を計算する。

Bitcoin寄付 / BTC Donation

Bitcoinを寄付しよう

BTC
Select Payment Method
Personal Info

Donation Total: BTC 0.0010

このブログの運営のためにBitcoinでの寄付を募集しています。お気持ち程度の寄付を頂けると管理者の励みになります。

Bitcoin寄付について知りたい方はこちらの記事へ

ビットコイン取引ならここ

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • サイトマップ
  • タグ一覧
  • プライバシーポリシー
  • お問い合わせ

Copyright © 2023 KD - Casual Developers Notes