JavaScriptオブジェクトとCrockfordのThe Good Parts


8

最近、JSでOOPを実行する方法についてかなり考えています。特に、カプセル化と継承に関してはそうです。

Crockfordによれば、classicalはnew()により有害であり、prototypeとclassicの両方が制限されています。これらのコンストラクターの使用は、カプセル化にクロージャーを使用できないことを意味します。

最近、私はカプセル化について次の2つの点を検討しました。

  1. カプセル化するとパフォーマンスが低下します。各オブジェクトのメソッドには異なるクロージャーがあるため(各オブジェクトには異なるプライベートメンバーがあるため)、プロトタイプではなく各メンバーオブジェクトに関数を追加できます。

  2. カプセル化によって、醜い「var that = this」の回避策が強制され、プライベートヘルパー関数が接続されているインスタンスにアクセスできるようになります。それか、毎回privateFunction.apply(this)でそれらを呼び出すようにしてください。

私が言及した2つの問題のいずれかの回避策はありますか?そうでない場合でも、カプセル化はそれだけの価値があると考えていますか?

補足:Crockfordが説明する機能パターンでは、new()とconstructor.prototypeの使用を完全に忘れているため、パブリックメンバーにのみ触れるパブリックメソッドを追加することもできません。古典的な継承とnew()を使用するだけでなく、Super.apply(this、arguments)を呼び出してプライベートメンバーと特権付きメソッドを初期化するハイブリッドアプローチは優れていますか?


Dojoなど、これをすべて提供するJavaScriptライブラリがいくつかあると思います。TypeScriptもあります。
MarkJ

@MarkJ Dojoのクラスシステムは、ガジリオンの疑似古典的継承ライブラリと同じように見え、カプセル化に関しては何も提供していません。
ジョナサン

ところで、その記事はメモリ使用量を軽視しています。メソッドの量に応じてメモリ使用量が増加することはまったく考慮されていません。たとえば、「クラス」に20のメソッドがある場合、機能パターンは彼の数値で3000 mbかかりますが、プロトタイプは150 mbかかります。メソッドの量。それは... と比較O(1)するようなものですO(n)n = 2
Esailija

回答:


2

カプセル化は本当にトリッキーであり、おそらくJavaScriptでの取り組みに値するものではありません。機能し、希望するすべてを実行するメソッド(プライベートフィールド、スーパークラスおよびプライベートメソッドへのアクセス)は、次の(おそらく非常に醜く、改善可能な)ソリューションです。

function SomeClass() {

    var parent = SomeSuperClass(),
        somePrivateVar;

    return Object.create(parent, {
        somePrivateVar: {
            get: function() {
                return somePrivateVar;
            },
            set: function(value) {
                somePrivateVar = value;
            }
        },
        doSomething: {
            value: function(data) {
                someHelperFunction.call(this, data);
            }
        }
    });
}

function someHelperFunction(data) {
    this.someMethod(data);
}

この種の作品は、あなたがそれを期待するようにあなたがプライベートフィールドとメソッドと継承を持つことを可能にします。しかし、私はそれが好きではありません-しかし、純粋なJavaScriptで実現できるすべての可能性の中で最高です。

多くのJavaScriptを使用して新しいプロジェクトを開始する必要がある場合は、おそらくTypeScriptを詳しく調べます。それは必要に応じてJavaScriptを改善し(IMHO)、静的な型付け、継承、カプセル化などすべてを提供します。


今、それは価値がありますか?考慮すべき重要な点が2つあると思います。カプセル化はおそらく開発時に役立ちますが、実行時には確かに役立ちません。あなたが決める必要があると思います。カプセル化を行わずにパフォーマンスを向上させるか、カプセル化してあまり美しくないコードを作成するか、おそらくデザインは優れていますが、実行時にオーバーヘッドが発生します。


私はこのパターンを知っています。これはCrockfordが機能と呼んでいるものですが、親を子のプロトタイプとして設定した点が少し異なります。問題は正確です。カプセル化は私のOPで言及されたオーバーヘッドに値しますか(そしてあなたのコードに存在しますか)?このオーバーヘッドを回避する方法はありますか?カプセル化チェックはコンパイル時に行われるため、TypeScriptは興味深いように見えます。つまり、コンパイルされたJSにオーバーヘッドはありませんが、とりあえず、生のJSを使用しています。ちなみに、一貫性を保つために、コードはおそらくnewなしでvar parent = SomeSuperClass()を読み取る必要があります。
ジョナサン

@ジョナサン:私は「価値のある」質問についていくつかの情報を追加しました。
BrunoSchäpper12年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.