1. ホーム
  2. javascript

[解決済み] JavaScriptにはinterface型(Javaの'interface'など)はありますか?

2022-03-24 13:39:23

質問内容

勉強中です JavaScriptでOOPを作る方法 . インターフェイスの概念があるのか(Javaの interface )?

だから、リスナーを作ることができるようになるのですが......。

どのように解決するのですか?

なぜなら、"このクラスはこれらの関数を持たなければならない"という概念がない(つまり、インターフェース自体がない)。

  1. JavaScriptの継承は、クラスではなくオブジェクトをベースにしています。 そのことに気づくまでは、たいしたことではありません。
  2. JavaScriptは 極めて 適切なメソッドを持つオブジェクトを作成することができ、そのオブジェクトはインターフェースに適合することになります。 そして、それを適合させたすべてのものをアンデファインする。 . そうすると、型システムを覆すのはとても簡単で、たとえ偶発的なものであったとしても、型システムを覆すことはできません。-- 偶発的にでも!)型システムを破壊するのはとても簡単で、そもそも型システムを作ろうとすること自体に価値がないでしょう。

その代わり、JavaScriptでは ダックタイピング . (アヒルのように歩き、アヒルのように鳴けば、JSが気にする限り、それはアヒルです)。もし、あなたのオブジェクトが quack()、walk()、fly() メソッドを持っていれば、コードは、歩いたり、鳴いたり、飛んだりするオブジェクトを期待するところならどこでも、いくつかの "Duckable"インターフェースの実装を必要とせずにそれを使用することができます。インターフェイスとは、まさにコードが使用する関数のセット(およびその関数の戻り値)であり、ダックタイピングでは、それを無料で手に入れることができます。

さて、だからといって、もしあなたが some_dog.quack() TypeErrorが発生します。 率直に言って、もし犬に鳴けと言っているのなら、もう少し大きな問題があります。アヒルの型付けがうまくいくのは、いわばすべてのアヒルを一列に並べているときで、犬やアヒルを一般的な動物として扱わない限り混在させないようにしています。 言い換えれば、インターフェイスが流動的であっても、インターフェイスは存在します。そもそも、犬が鳴いたり飛んだりすることを期待するコードに犬を渡すのは、しばしばエラーになります。

しかし、もし自分が正しいと思っているのなら、特定のメソッドを使おうとする前にその存在をテストすることで、quacking-dogの問題を回避することができるのです。次のようなものです。

if (typeof(someObject.quack) == "function")
{
    // This thing can quack
}

だから、使えるメソッドを全部チェックしてから使うことができる。しかし、この構文はちょっと醜いですね。もう少しきれいな方法があります。

Object.prototype.can = function(methodName)
{
     return ((typeof this[methodName]) == "function");
};

if (someObject.can("quack"))
{
    someObject.quack();
}

これは標準的なJavaScriptなので、どんなJSインタプリタでも動作するはずです。 英語のように読めるという利点もある。

モダンブラウザ(つまり IE 6-8 以外のほとんどのブラウザ)では、このプロパティの表示を抑制する方法もあります。 for...in :

Object.defineProperty(Object.prototype, 'can', {
    enumerable: false,
    value: function(method) {
        return (typeof this[method] === 'function');
    }
}

問題は、IE7 のオブジェクトには .defineProperty は、IE8 では、ホストオブジェクト (つまり DOM 要素など) にしか作用しないとされています。 互換性が問題になる場合は .defineProperty . (IE6については、中国以外ではもうむしろ関係ないので、触れません)。

もう一つの問題は、コーディングスタイルによっては、誰もが悪いコードを書くと思い込んでいて、そのために Object.prototype を盲目的に使おうとする人がいるかもしれないので for...in . それを気にする人、あるいは使っている人(IMO ブロークン ) のコードでは、少し異なるバージョンを試してみてください。

function can(obj, methodName)
{
     return ((typeof obj[methodName]) == "function");
}

if (can(someObject, "quack"))
{
    someObject.quack();
}