mongolyyのブログ

開発(Javascript, Typescript, React, Next.js)や開発手法(スクラム, アジャイル)、勉強したことについて色々書ければと。

「オブジェクト指向 JavaScriptの原則」を読んだ

はじめに

メーカーのコーポレート部門でソフトウェアエンジニアとして働いているモンゴルです。 今回、3連休に次の書籍を読んだので、その感想を書いていこうと思います。

感想

プリミティブか参照型か意識するようになった

ラッパーオブジェクトの存在により、プリミティブ型であってもメソッドが使えていたということもあり、以前はあまり意識していませんでした。
本書を読んで、ラッパーオブジェクトの仕様などが丁寧に説明されており、非常にわかりやすく理解できました。
また、 type ofinstanceof に対して、正直なんとなーくで使っていましたが、本書を読んで、プリミティブ型の場合は type of でそれ以外の独自のオブジェクトについては instanceof という理解が進みました

内部プロパティを知った

関数オブジェクトは [[Call]]、通常のオブジェクトは [[Put]][[Set]][[Get]] などの内部プロパティ、メソッドを保有していることを知りました。 またこれらの値を使って、関数かどうか判定したり、setter、getterの処理が保有されていることを知りました。
内部プロパティの一部は Object.defineProperty() で設定ができるということも初めて知りました。

これを知って、TypeScriptのreadonlyやgetterの記載をしたときに、 Object.defineProperty() を使用したコードにトランスパイルされているのでは?と感じ、実際に次のコードをTypeScript Playgroundでトランスパイルしてみました。

class Employee {
  readonly id: string;
  name: string;

  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }

  get label() {
    return `名前は${name}`;
  }
}

TypeScript: TS Playground - An online editor for exploring TypeScript and JavaScript

面白いことに、TargetをES5としたときと、ES2015にした場合で結果は異なりました。

  • ES5の場合
"use strict";
var Employee = /** @class */ (function () {
    function Employee(id, name) {
        this.id = id;
        this.name = name;
    }
    Object.defineProperty(Employee.prototype, "label", {
        get: function () {
            return "\u540D\u524D\u306F".concat(name);
        },
        enumerable: false,
        configurable: true
    });
    return Employee;
}());

本書で習ったObject.definePropertyが使われてました。

  • ES2015にした場合
"use strict";
class Employee {
    constructor(id, name) {
        this.id = id;
        this.name = name;
    }
    get label() {
        return `名前は${name}`;
    }
}

classが追加されたせいなのか、トランスパイルされた結果もTypeScriptで実装したものとほぼ同一になっていました。
確証はありませんが、classが追加されたことにより、このような変化が生じたのだと思いました。

おわりに

JavaScript初級者という方で、言語仕様をもっと知りたいという方におすすめの一冊でした。
一方、ES2015からクラスが追加されていたり大きな変更があるのに対し、本書はES5ベースで書かれているので、無用とまではいかずとも、注意が必要にも感じました。

最後に、自分の仕事観点での、個人的感想です。
普段はTypeScriptを使っているのですが、仕様がJavaScriptに由来するものなのか、TypeScriptに由来するものなのか意識できていなかったということに気付かされました。

通常のTypeScriptを使用した実装では直接役に立たないかもしれませんが、何か不具合調査のためにトランスパイルされたコードを読んだり、JavaScriptで書かれたライブラリのコードをサクッと読む場合も、JavaScript本来の仕様を知っていることで、理解のしやすさ、深さは変わりそうだなと思いました。
本書はその役に立ちそうにも感じましたし、他の本や情報源も使って、継続的に学習したいと感じました。