ホームページ >よくある問題 >jsプロトタイプとプロトタイプチェーンとは何ですか

jsプロトタイプとプロトタイプチェーンとは何ですか

百草
百草オリジナル
2023-06-14 11:34:478128ブラウズ

js プロトタイプとプロトタイプ チェーンは次のとおりです。 1. プロトタイプ、すべての関数はデフォルトで「プロトタイプ」のようなパブリックで列挙不可能な属性を持ち、これは別のオブジェクト (プロトタイプ) を指します。 2. プロトタイプ チェーン: オブジェクトのプロパティまたはメソッドにアクセスするとき、オブジェクトはまずそれ自体からそれを探します。見つからない場合は、プロトタイプ内、つまりそのオブジェクトの「プロトタイプ」内でそれを探します。プロトタイプで見つからない場合は、コンストラクターにそのような属性がなくても、プロトタイプの後ろにあるプロトタイプでそれを探し、プロトタイプ チェーンと呼ばれるチェーン構造を形成します。

jsプロトタイプとプロトタイプチェーンとは何ですか

このチュートリアルのオペレーティング システム: Windows 10 システム、JavaScript ECMAScript 2021 バージョン、DELL G3 コンピューター。

1. プロトタイプ

プロトタイプ: すべての関数には、デフォルトで「プロトタイプ」のようなパブリックで列挙不可能な属性があり、別のオブジェクトを指します。このオブジェクトはプロトタイプです。オブジェクト (関数もオブジェクト) が定義されるたびに、暗黙的プロトタイプと呼ばれる __proto__ 属性が生成されます。この __proto__ 属性は、このオブジェクトのコンストラクターのプロトタイプ (明示的プロトタイプと呼ばれます) を指します。すべてのオブジェクトはプロトタイプからプロパティを「継承」します。

最初に例を見て、Student クラスを作成し、クラスのインスタンス オブジェクト Student を作成します。

class Student{
    constructor(name, score) {
        this.name = name;
        this.score = score;
    }
    introduce() {
        console.log(`我是${this.name},考了${this.score}分。`)
    }
}
const student = new Student('张三', 99)
console.log('student', student); // student Student { name: '张三', score: 99}
student.introduce(); // 我是张三,考了99分。

コンソールはプロパティとメソッドにアクセスできます。

jsプロトタイプとプロトタイプチェーンとは何ですか

しかし、コンソールに直接 Student と入力すると、名前とスコア属性のみがあり、導入メソッドはありませんが、[[プロトタイプ]] があることがわかります。属性。2 つの角かっこを使用します。

jsプロトタイプとプロトタイプチェーンとは何ですか

[[プロトタイプ]] を展開すると、導入メソッドが [[プロトタイプ]] にあることがわかります。

jsプロトタイプとプロトタイプチェーンとは何ですか

[[Prototype]] 属性は、Student オブジェクトの暗黙的なプロトタイプと呼ばれます。オブジェクトのプロパティやメソッドを見つけたいとき、現在のオブジェクトで見つからない場合は、現在のオブジェクトの暗黙のプロトタイプ [[Prototype]] 属性にアクセスしてそれらを見つけます。

プロトタイプには、.__proto__ 属性を通じてアクセスできます。__proto__ の両側に 2 つのアンダースコアがあることに注意してください。

jsプロトタイプとプロトタイプチェーンとは何ですか

Student() コンストラクターには、prototype 属性もあります。Student() コンストラクターのプロトタイプ属性は、実際には Student オブジェクトの __proto__ 属性と同じです。

1.jsプロトタイプとプロトタイプチェーンとは何ですか

以下は説明するための図です:

jsプロトタイプとプロトタイプチェーンとは何ですか

したがって、コンストラクターのプロトタイプ属性は、インスタンス オブジェクトの __proto__ 属性、コンストラクターのプロトタイプ属性は明示的プロトタイプと呼ばれ、インスタンス オブジェクトの __proto__ 属性は暗黙的プロトタイプと呼ばれます。

2. プロトタイプ チェーン

プロトタイプ チェーン: オブジェクトのプロパティまたはメソッドにアクセスするとき、オブジェクトはまずそれを自分自身から探します。見つからない場合は、プロトタイプ、つまりコンストラクターのプロトタイプである __proto__ でそれを検索します。プロトタイプで見つからない場合、つまり、コンストラクターにそのような属性がありません。コンストラクターもオブジェクトであり、__proto__ も持っている場合、プロトタイプを検索します。このプロトタイプは、プロトタイプ チェーンと呼ばれるチェーン構造を形成します。プロトタイプ チェーンは、本質的にオブジェクトの継承関係を記述します。

別の例を見てみましょう。パーソン クラスを作成し、そのパーソン クラスを継承する Teacher クラスを作成し、インスタンス オブジェクト Teacher を作成します。

class Person {
    constructor(name) {
        this.name = name;
    }
    drink(){
        console.log('喝水');
    }
}
class Teacher extends Person {
    constructor(name, subject) {
        super(name);
        this.subject = subject;
    }
    teach() {
        console.log(`我是${this.name}, 教${this.subject}。`)
    }
}
const teacher = new Teacher('哈默', '前端开发')
console.log('teacher', teacher);
teacher.teach();
teacher.drink();

コンソールの出力は次のとおりです。が続き、教師は、teach() メソッドと Drink() メソッドを実行できます。

jsプロトタイプとプロトタイプチェーンとは何ですか

Teacher オブジェクトを展開すると、これら 2 つのメソッドが見つからないことがわかりました。そのため、オブジェクトのプロトタイプ、つまり __proto__ 属性を探し、teach( ) メソッドを展開して、__proto__ 属性のレイヤーで、 Drink() メソッドを見つけます。

jsプロトタイプとプロトタイプチェーンとは何ですか

次は説明のための図です:

jsプロトタイプとプロトタイプチェーンとは何ですか

可以看到,teacher实例对象本身是没有teach()方法的,这时就会去teacher对象的__proto__隐式原型指向的Teacher.prototype显式原型上去找,此时找到了teach()方法并执行;同时,Teacher.prototype上仍然没有找到drink()方法,而Teacher.prototype也是一个对象,有自己的__proto__隐式原型,那么就去Teacher.prototype.__proto__上去找,Teacher.prototype.__proto__会指向Person()构造函数的显式原型Person.prototype,此时找到了drink()方法并执行,这就是原型链。

注:

(1)通过__proto__形成原型链而非protrotype。

(2)__proto__属性是对象所独有的。

(3)prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__属性。

三、判断对象自身是否有某属性或方法

hasOwnProperty()方法会返回一个布尔值,用于判断对象自身是否有某属性或方法。返回true,代表是该对象自身的属性或方法;返回false,代表是该对象原型上的属性或方法。

由于Person类继承自Object类,那么执行teacher.hasOwnProperty()方法时,实际会找到Object.prototype中的hasOwnProperty()方法并执行。

因此,所有继承了Object的对象都会继承到hasOwnProperty方法。

同时可以看到,Object.prototype.__proto__ 的值为 null ,即 Object.prototype 没有原型,所以可以想象在原型链中,当找到顶层原型还没有属性时,那就是没有这个属性,返回返回undefined。

jsプロトタイプとプロトタイプチェーンとは何ですか

instanceof 运算符:用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

看一个例子,使用typeof判断array的数据类型时,返回的是object,因此无法使用typeof判断array的类型。

const object = {};
const array = [];
// 使用typeof判断数据类型,array返回的是object 
console.log(typeof object); // object
console.log(typeof array); // object

下面使用instanceof运算符判断array的数据类型:

// 使用instanceof判断数据类型
const flagObject = object instanceof Array;
const flagArray = array instanceof Array;
console.log(flagObject); // false
console.log(flagArray); // true

object instanceof Array返回false,表示Array.prototype不在object的原型链上;array instanceof Array返回true,表示Array.prototype在array的原型链上,由此可以区分object和array的数据类型。

也可通过控制台查看object和array的原型。

注:[] instanceof Object 为 true

以上がjsプロトタイプとプロトタイプチェーンとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。