インタビュアー: js プロトタイプについて話します

プロトタイプ オブジェクトについて 1 分で学ぶ

jsは関数オブジェクトと通常のオブジェクトに分かれており、各オブジェクトには__proto__属性がありますが、prototype属性を持つのは関数オブジェクトだけで、prototype属性は関数のプロトタイプオブジェクトです。

たとえば、コンストラクターは new を介してインスタンス オブジェクトを実現し、インスタンス オブジェクトの __proto__ はプロトタイプ オブジェクトを指し、コンストラクター プロトタイプもプロトタイプ オブジェクトを指します。

例えば:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
}

var person1 = new Person("Alice", 25);
var person2 = new Person("Bob", 30);

person1.sayHello(); // 输出:Hello, my name is Alice and I am 25 years old.
person2.sayHello(); // 输出:Hello, my name is Bob and I am 30 years old.

Person は関数およびコンストラクターであり、そのプロトタイプはプロトタイプ オブジェクトを指します。Person.prototype オブジェクトを使用して、各 Person オブジェクトに共通のメソッド sayHello を定義します。このメソッドは、キャラクターの名前と年齢を表す文字列を出力します。

new キーワードを使用して 2 つの Person オブジェクトを作成し、それぞれ sayHello メソッドを呼び出して、異なる文字列を出力します。これは、person1 と person2 はどちらも Person.prototype オブジェクトの sayHello メソッドを継承していますが、プロパティ値が異なるためです。

プロトタイプオブジェクトとは正確には何ですか?

プロトタイプ オブジェクトは、いくつかの共通のプロパティとメソッドを含むテンプレートと比較でき、それを使用して新しいオブジェクトを作成できます。テンプレートを使用して同じ製品をすばやく作成できるように、各製品の特定の詳細は異なる場合がありますが、基本的な構造と特性は同じです.

たとえば、モデル、ブランド、最高速度、加速度などの一般的な属性とメソッドを含む「車」のプロトタイプ オブジェクトを作成できます。次に、このプロトタイプ オブジェクトを使用して、自動車、トラック、オートバイなど、さまざまな自動車モデルを作成できます。これらの自動車モデルはすべて同じプロトタイプ オブジェクトに基づいて作成されているため、基本的な特性と構造はすべて同じですが、自動車やトラックの寸法、積載量など、特定の詳細はわずかに異なる場合があります。

同様に、JavaScript では、プロトタイプ オブジェクトを使用して複数のオブジェクトをすばやく作成できます。これらのオブジェクトはすべて同じ基本的な特性とメソッドを持っています。このプロトタイプ オブジェクト ベースのアプローチは、コードの再利用を実現し、開発効率を向上させることができます。

プロトタイプオブジェクトができること

上記の例は、メソッドとメソッドを関数のプロトタイプ オブジェクト、つまりプロトタイプ オブジェクトに追加できることを示しており、これらは将来この関数によって新しく作成されるオブジェクトに継承されます。

プロトタイプ オブジェクトは JavaScript で重要な役割を果たし、多くの場合、次の方法で使用されます。

継承の実現:プロトタイプ オブジェクトを通じて、新しいオブジェクトを作成し、プロトタイプ オブジェクトのプロパティとメソッドを継承できます。このプロトタイプベースの継承方法により、オブジェクト指向プログラミングをより便利に実装できます。

共有プロパティとメソッド:プロトタイプ オブジェクトでプロパティとメソッドを定義することにより、複数のオブジェクトがこれらのプロパティとメソッドを共有できるようになります。これにより、メモリ使用量が削減され、コードの効率が向上します。

オブジェクトの拡張:プロトタイプ オブジェクトを変更することにより、実行時にオブジェクトのプロパティとメソッドを拡張できます。オブジェクトを動的に拡張するこの方法により、オブジェクトをより柔軟に扱うことができます。

toString一般的に使用されるいくつかのメソッドと関数を実装します。プロトタイプ オブジェクトには、 、などの一般的に使用されるメソッドと関数が既に含まれていますvalueOfプロトタイプオブジェクトに対応するメソッドを定義することで、オブジェクトにこれらの共通メソッドを実装できるため、開発プロセスでより便利に使用できます。

栗を取る:

function Person() {}

Person.prototype.sayHello = function() {
  console.log("Hello, I'm a person.");
}

function Student() {}

Student.prototype = Object.create(Person.prototype);

const alice = new Student();

alice.sayHello(); // 输出:Hello, I'm a person.

この例では、プロトタイプ チェーンを介して alice オブジェクトのプロトタイプ オブジェクトにアクセスし、そのプロトタイプ オブジェクトを介して sayHello メソッドを呼び出します。Student 関数のプロトタイプ オブジェクトは Person 関数のプロトタイプ オブジェクトを継承するため、alice オブジェクトも Person 関数のプロトタイプ オブジェクトのメソッドとプロパティを継承します。

プロト

__proto__オブジェクトのプロトタイプを指す JavaScript の組み込みプロパティです。JavaScript では、各オブジェクトには、オブジェクトのすべてのプロパティとメソッドを含むプロトタイプ オブジェクトがあり、オブジェクトの共通のプロパティとメソッドを定義するために使用されます。__proto__プロパティは、オブジェクトのプロトタイプを表すために使用されます。

たとえば、次のコードを使用して単純なオブジェクトを作成し、その__proto__プロパティを表示できます。

const person = {
  name: "Alice",
  age: 25
};

console.log(person.__proto__); // 输出:Object {}

上記のコードでは、name と age の 2 つのプロパティを持つ person という名前のオブジェクトを定義しました。次に、console.log() メソッドを使用して person.__proto__ 属性を出力します。この属性は、このオブジェクトのプロトタイプ オブジェクト (Object オブジェクト) を指します。

__proto__ は非標準の属性であり、ECMAScript 2015 標準では廃止されていることに注意してください。オブジェクトのプロトタイプは、Object.getPrototypeOf() メソッドまたは Object.setPrototypeOf() メソッドを使用して操作する必要があります。たとえば、次のメソッドを使用してオブジェクトのプロトタイプを取得できます。

const person = {
  name: "Alice",
  age: 25
};

console.log(Object.getPrototypeOf(person)); // 输出:Object {}

上記のコードでは、Object.getPrototypeOf() メソッドを使用して、Object オブジェクトを返す person オブジェクトのプロトタイプを取得します。

__proto__ は何をしますか?

オブジェクトのプロトタイプを表示

__proto__ を使用してオブジェクトのプロトタイプにアクセスし、その継承関係を理解することができます。例えば:

function Person() {}

const alice = new Person();

console.log(alice.__proto__); // 输出:Person {}

この例では、Person 関数を作成し、それを使用して alice オブジェクトを作成します。次に、Person 関数のプロトタイプ オブジェクトである alice.__proto__ を介して、alice オブジェクトのプロトタイプにアクセスします。

オブジェクトのプロトタイプ チェーンを作成する

__proto__ を使用して、オブジェクトのプロトタイプ チェーンを作成できます。例えば:

function Person() {}

const alice = {
  name: "Alice"
};

alice.__proto__ = Person.prototype;

console.log(alice instanceof Person); // 输出:true

この例では、空のオブジェクト alice を定義し、そのプロトタイプ チェーンを Person 関数のプロトタイプ オブジェクトにポイントします。alice オブジェクトのプロトタイプ チェーンは Person 関数のプロトタイプを継承しているため、Person 型のインスタンスと見なすことができます。

オブジェクトのプロトタイプを変更します

__proto__ を使用して、オブジェクトのプロトタイプ オブジェクトを動的に変更できます。例えば:

function Person() {}

const alice = new Person();

alice.__proto__ = {
  sayHello() {
    console.log("Hello, I'm a new object.");
  }
};

alice.sayHello(); // 输出:Hello, I'm a new object.

この例では、Person オブジェクト alice を作成し、alice.__proto__ を使用してそのプロトタイプ オブジェクトを動的に変更し、そのプロトタイプ オブジェクトを新しいオブジェクトに置き換えました。最後に、 alice.sayHello() メソッドが呼び出されると Hello, I'm a new object. が出力され、alice オブジェクトのプロトタイプが正常に置き換えられたことを示します。

試作品チェーン

オブジェクトのプロパティを取得しようとするときに、オブジェクト自体にこのプロパティがない場合は、オブジェクトの '_ _ proto_ _' プロパティ (つまり、そのコンストラクタの 'prototype' プロパティ) に移動して検索します。この検索されたリンクがプロトタイプ チェーンです。

例を参照してください。

  // 构造函数
  function Foo(name,age){
    this.name=name;
    this.age=age;
  }
  Object.prototype.toString=function(){
   //this是什么要看执行的时候谁调用了这个函数。
   console.log("I'm "+this.name+" And I'm "+this.age);
  }
  var fn=new Foo('小明',19);
  fn.toString(); //I'm 小明 And I'm 19
  console.log(fn.toString===Foo.prototype.__proto__.toString); //true
  
  console.log(fn.__proto__ ===Foo.prototype)//true
  console.log(Foo.prototype.__proto__===Object.prototype)//true
  console.log(Object.prototype.__proto__===null)//true

理解を助けるために絵に来てください。

要約する

1. すべての参照型 (配列、関数、オブジェクト) は、プロトタイプを通じてプロパティ (null を除く) を自由に拡張できます。

2. すべての参照型には「_ _ proto_ _」属性があります (通常のオブジェクトである暗黙のプロトタイプとも呼ばれます)。

3. すべての関数には「prototype」属性があります (これは明示的なプロトタイプとも呼ばれ、通常のオブジェクトでもあります)。

4. すべての参照型について、その '_ _ proto_ _' 属性はそのコンストラクターの 'prototype' 属性を指します。(2と3を組み合わせる)

5. オブジェクトのプロパティを取得しようとするとき、オブジェクト自体にこのプロパティがない場合は、オブジェクトの '_ _ proto_ _' プロパティ (つまり、そのコンストラクタの 'prototype' プロパティ) に移動して、それ。これがプロトタイプチェーンです。

 

おすすめ

転載: blog.csdn.net/weixin_39570751/article/details/130101516