サーチ…


標準関数プロトタイプ

まず、コンストラクタとして使用するFoo関数を定義します。

function Foo (){}

Foo.prototypeを編集することで、 Fooすべてのインスタンスで共有されるプロパティとメソッドを定義できます。

Foo.prototype.bar = function() {
  return 'I am bar';
};

newキーワードを使用してインスタンスを作成し、メソッドを呼び出すことができます。

var foo = new Foo();

console.log(foo.bar()); // logs `I am bar`

Object.keyとObject.prototype.keyの違い

Pythonのような言語とは異なり、コンストラクタ関数の静的プロパティはインスタンスに継承されません 。インスタンスは、プロトタイプを親クラスのプロトタイプから継承したプロトタイプのみを継承します。静的プロパティは継承されません。

function Foo() {};
Foo.style = 'bold';

var foo = new Foo();

console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined

Foo.prototype.style = 'italic';

console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'

プロトタイプからの新しいオブジェクト

JavaScriptでは、どのオブジェクトも別のオブジェクトのプロトタイプになる可能性があります。オブジェクトが別のオブジェクトのプロトタイプとして作成されると、そのオブジェクトはすべての親のプロパティを継承します。

var proto = { foo: "foo", bar: () => this.foo };

var obj = Object.create(proto);

console.log(obj.foo);
console.log(obj.bar());

コンソール出力:

> "foo"
> "foo"

注意 Object.createはECMAScript 5から利用できますが、ここではECMAScript 3のサポートが必要な場合はpolyfillを使用します

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

出典: http : //javascript.crockford.com/prototypal.html


Object.create()

Object.create()メソッドは、指定されたプロトタイプオブジェクトとプロパティを使用して新しいオブジェクトを作成します。

構文: Object.create(proto[, propertiesObject])

パラメータ

  • proto (新しく作成されたオブジェクトのプロトタイプでなければならないオブジェクト)
  • propertiesObject (オプション、未定義でない場合は、列挙可能なプロパティ(すなわち、プロトタイプチェーンに沿って列挙可能なプロパティではなくプロパティ自体に定義されているプロパティ)を持つオブジェクトは、新しく作成されたオブジェクトに追加するプロパティ記述子を指定します。これらのプロパティは、Object.defineProperties()の2番目の引数に対応します。

戻り値

指定されたプロトタイプオブジェクトとプロパティを持つ新しいオブジェクト。

例外

protoパラメータがnullでもオブジェクトでもない場合は、 TypeError例外が発生します。

プロトタイプ継承

prototypeと呼ばれる単純なオブジェクトがあるとします。

var prototype = { foo: 'foo', bar: function () { return this.foo; } };

今、私たちはと呼ばれる別のオブジェクトたいobjから継承されprototypeと言うと同じで、 prototypeプロトタイプであるobj

var obj = Object.create(prototype);

prototypeすべてのプロパティとメソッドがobjに利用できるようになりました。

console.log(obj.foo);
console.log(obj.bar());

コンソール出力

"foo"
"foo"

プロトタイプの継承はオブジェクト参照を介して内部的に行われ、オブジェクトは完全に変更可能です。つまり、プロトタイプに対して行った変更は、プロトタイプがプロトタイプである他のすべてのオブジェクトに即座に影響します。

prototype.foo = "bar";
console.log(obj.foo);

コンソール出力

"bar"

Object.prototypeはすべてのオブジェクトのプロトタイプですので、特にサードパーティのライブラリを使用している場合は、特に混乱しないようにしてください。

Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);

コンソール出力

"foo"
"foo"

楽しい事実私はこれらの例を作るためにブラウザコンソールを使い、このbreakingLibrariesプロパティを追加してこのページをbreakingLibrariesました。


擬似古典的継承

これはプロトタイプがどれほど強力かを示すプロトタイプの継承を使用して古典的な継承をエミュレートしたものです。他の言語のプログラマーにとって、その言語をより魅力的にするために作られました。

6

重要な注記 :ES6以降、言語は従来のクラスをシミュレートするため、擬似的な継承を使用することは意味がありません。 ES6を使用していない場合は、ES6を使用する必要があります。あなたがまだ古典的な継承パターンを使用したいと思っていて、あなたがECMAScript 5以下の環境にいるなら、疑似古典があなたの最良の賭けです。

「クラス」は、 newオペランドで呼び出されるように作られた関数であり、コンストラクタとして使用されます。

function Foo(id, name) {
    this.id = id;
    this.name = name;
}

var foo = new Foo(1, 'foo');
console.log(foo.id);

コンソール出力

1

fooはFooのインスタンスです。JavaScriptコーディング規約では、関数が大文字の大文字小文字で始まる場合は、( newオペランドを使用して)コンストラクタとして呼び出すことができます。


"クラス"にプロパティやメソッドを追加するには、それらをプロトタイプに追加する必要があります。これはコンストラクタのprototypeプロパティにあります。

Foo.prototype.bar = 'bar';
console.log(foo.bar);

コンソール出力

バー

実際、Fooが "コンストラクタ"として行っているのは、 Foo.prototypeをプロトタイプとしてオブジェクトを作成することだけです。


すべてのオブジェクトのコンストラクタへの参照を見つけることができます

console.log(foo.constructor);

関数Foo(id、name){...

console.log({ }.constructor);

function Object(){[ネイティブコード]}

また、オブジェクトがinstanceof演算子で指定されたクラスのインスタンスであるかどうかをチェックする

console.log(foo instanceof Foo);

真実

console.log(foo instaceof Object);

真実

オブジェクトのプロトタイプを設定する

5

ES5 +では、 Object.create関数を使用して、プロトタイプとして他のObjectを持つObjectを作成できます。

const anyObj = {
    hello() {
        console.log(`this.foo is ${this.foo}`);
    },
};

let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';

objWithProto.hello(); // "this.foo is bar"

プロトタイプなしで明示的にオブジェクトを作成するには、プロトタイプとしてnullを使用しnull 。これは、ObjectがObject.prototypeから継承しないことを意味し、存在チェック辞書に使用されるObject、たとえば

let objInheritingObject = {};
let objInheritingNull = Object.create(null);

'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
6

ES6から、既存のObjectのプロトタイプはObject.setPrototypeOfを使用して変更できます。

let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});

obj.foo; // undefined
obj.bar; // "bar"

これは、 thisオブジェクトやコンストラクタを含むほとんどの場所で行うことができます。

注意:このプロセスは現在のブラウザでは非常に遅く、控えめに使用する必要があります。目的のプロトタイプでObjectを作成してみてください。

5

ES5以前では、手動で定義されたプロトタイプを使用してオブジェクトを作成する唯一の方法は、 newで構築することでした

var proto = {fizz: 'buzz'};

function ConstructMyObj() {}
ConstructMyObj.prototype = proto;

var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"

この動作は、Polycomを記述することが可能であることをObject.createに十分に近似しています。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow