1

ここで何が起こっているのか知りたいです。ご覧のとおり、range新しいrangeオブジェクトを作成するために呼び出されるコンストラクター関数を定義しました。rangeプロトタイプを介してコンストラクターを拡張し、単純なincludesメソッドを追加しました。新しいオブジェクトを作成し、の変数を使用しましたprangeオブジェクトでこのメソッドを使用しようとすると、すべてが正常に機能し、期待どおりに機能します。問題は、それを見ようとすると、タイプが未定義でメソッドがないp.prototypeことを教えてくれることです...え??p.prototype

何が起きてる??pオブジェクトはどうですか、そうでp.prototypeはありませんか?

    function range(from, to) {
        this.from = from;
        this.to = to;
    }


    range.prototype = {
        includes: function(x) { return this.from <= x && x <= this.to; },
    }

    var p = new range(1, 4);

    console.log(typeof p) //outputs object
    console.log(typeof p.prototype) //outputs undefined

    console.log(Object.getOwnPropertyNames(range.prototype)); //outputs includes
    console.log(Object.getOwnPropertyNames(p.prototype)); //throws error, p.prototype is not an object
4

4 に答える 4

2

問題は、それを見ようとすると、p.prototype型が未定義であることがわかります

そのとおりです。rangeコンストラクターによって作成されたオブジェクトにはプロパティがありませんが、基礎となるプロトタイプ (関数のプロパティprototypeから引き出される) があります。prototyperange

するとどうなるか見てみましょうnew range():

  1. JavaScript エンジンは、新しい空のオブジェクトを作成します。
  2. JavaScript エンジンは、そのオブジェクトの基礎となるプロトタイプ ( ではないprototype) を、 によって参照されるオブジェクトに割り当てますrange.prototype。(仕様では、このプロパティ —コードで直接アクセスすることはできませんが、以下を参照してください — は と呼ばれ[[Proto]]ます。)
  3. JavaScript エンジンは新しいオブジェクトrangeを参照して呼び出します。this
  4. が別のrangeオブジェクトを返さないと仮定すると(これは可能ですが、これは少しあいまいです)、 の結果はステップ 1 で作成された新しいオブジェクトです。new range

後で を使用するthis.includesと、次のようになります。

  1. エンジンは、実際のオブジェクトを調べて、プロパティがあるかどうかを確認しincludesます。
  2. 存在しないため、エンジンは[[Proto]]存在するかどうかを調べます
  3. あるので、それを使用します(そうでない場合は、 などを調べたでしょう[[Proto]][[Proto]]

ここで重要なことは次のとおりです。

  1. オブジェクトには基礎となるプロトタイプがあり、オブジェクト自体の名前付きプロパティを介してアクセスすることはできません。(実際、以前はそれらにまったく到達できませんでした。現在、ES5 では、Object.getPrototypeOf.)
  2. new SomeFunctionNameプロパティからプロトタイプを取得することによって作成されたオブジェクトSomeFunctionName.prototypeは、オブジェクトの完全に通常のプロパティですSomeFunctionName(関数は JavaScript のファースト クラス オブジェクトです)。

補足: ofをコードに置き換えています。一般に、それは機能しますが、私はそれを避けます。代わりに、によって参照される既存のオブジェクトを拡張します。(プロパティを置き換えるのではなく、プロパティを追加してください。)しかし、それはあなたの質問の中心ではありません。prototyperangerange.prototype

于 2012-11-03T23:37:51.897 に答える
0

私はあなたが望んでいたと思います:

range.prototype.includes = function(x) { 
    return this.from <= x && x <= this.to; 
}
于 2012-11-03T23:34:55.733 に答える
0

プロトタイプ オブジェクトを再定義したため、元のオブジェクトへの参照が消えています。この方法を試してください:

range.prototype.includes = function(x) { 
    return this.from <= x && x <= this.to;
}
于 2012-11-03T23:35:32.677 に答える
0
Number.prototype.myRound = function (decimalPlaces) {
    var multiplier = Math.pow(10, decimalPlaces);

    return (Math.round(this * multiplier) / multiplier);
};
于 2013-12-20T07:33:24.267 に答える