JS のプロトタイプチェーンと継承は JS の重要なポイントです。次の 3 つの例を通して詳しく説明します。
まずオブジェクト obj を定義します。オブジェクトのプロトタイプは obj._proto_ です。ES5 の getPrototypeOf メソッドを使用して、obj のプロトタイプが Object と等しいかどうかを判断して、存在するかどうかを証明します。 .prototype. obj のプロトタイプ。答えは true を返すため、存在します。次に、関数 foo() を定義します。どの関数にもそのプロトタイプ オブジェクト、つまり関数のプロトタイプがあり、インスタンス化されたオブジェクトは new を通じてその属性を共有できます。 2つの例を詳しく紹介します)。
function foo(){} foo.prototype.z = 3; var obj = new foo(); obj.x=1; obj.y=2; obj.x //1 obj.y //2 obj.z //3 typeof obj.toString; //function obj.valueOf(); // foo {x: 1, y: 2, z: 3} obj.hasOwnProperty('z'); //false
ここで、obj (_proto_) のプロトタイプは foo 関数のプロトタイプ属性を指し、foo.prototype のプロトタイプは Object.prototype を指し、プロトタイプ チェーンの末尾が null かどうかを確認するために hasOwnProperty を使用します。 z 属性は obj にあります。 false と表示されます。obj に z 属性はありませんが、そのプロトタイプ チェーンを検索すると、foo.prototype にあることがわかり、最初は obj.z=3 になります。この場合、 obj.valueOf() と toString は両方とも Object.prototype 上にあるため、すべてのオブジェクトのプロトタイプは Object.prototype であるため、すべてのオブジェクトはこれら 2 つの属性を持ちます。もちろん、次の特殊なケース
を除きます。var obj2 = Object.create(null); obj2.valueOf(); //undefined
Object.create() は空のオブジェクトを作成し、このオブジェクトのプロトタイプはパラメーターを指します。次の包括的な例は、クラスを実装して別のクラスを継承する方法を示しています
//声明一个构造函数Person function Person(name,age){ this.name = name; this.age = age; } Person.prototype.hi = function (){ console.log('Hi,my name is ' + this.name +',my age is '+this.age); }; Person.prototype.LEGS_NUM=2; Person.prototype.ARMS_NUM=2; Person.prototype.walk = function (){ console.log(this.name+' is walking !'); }; function Student(name,age,classNum){ Person.call(this,name,age); this.classNum = classNum; } //创建一个空对象 Student.prototype = Object.create(Person.prototype); //constructor指定创建一个对象的函数。 Student.prototype.constructor = Student; Student.prototype.hi = function (){ console.log('Hi,my name is ' + this.name +',my age is '+this.age+' and my class is '+this.classNum); }; Student.prototype.learns = function (sub){ console.log(this.name+' is learning '+sub); }; //实例化一个对象Bosn var Bosn = new Student('bosn',27,'Class 3'); Bosn.hi(); //Hi,my name is bosn,my age is 27 and my class is Class 3 Bosn.LEGS_NUM; //2 Bosn.walk(); //bosn is walking ! Bosn.learns('Math'); //bosn is learning Math
コンストラクター person と Student の this はインスタンス化されたオブジェクト (Bosn) を指し、このオブジェクトのプロトタイプはコンストラクターのプロトタイプを指します。
Object.create() メソッドを使用して、空のオブジェクトを作成します。このオブジェクトのプロトタイプは Person.prototype です。この方法で記述する利点は、Person.prototype プロパティに影響を与えずに Studnet.prototype を自分で作成できることです。サブクラス Student は基本クラス Person を継承するため、任意の属性、および Person.prototype の元の属性を継承できます。 Person.prototype = Student.prototype と直接記述すると、両方とも同じオブジェクトを指し、Student.prototype に属性を追加すると、同じ属性が Person のプロトタイプ チェーンに追加されます。
コンストラクター Student の call メソッドの場合、この内部は新しく作成された Student のインスタンス化されたオブジェクトを指しており、呼び出しを通じて継承が実装されます。
Student.prototype.constructor = Student、この文の意味は、Student.prototype オブジェクトを作成する関数として Student を指定することです。この文が書かれていない場合、オブジェクトの関数は person のままです。
継承については、3 つの実装方法があります。
function Person(name,age){ this.name = name; this.age = age; } function Student(){ } Student.prototype = Person.prototype; //1 Student.prototype = Object.create(Person.prototype); //2 Student.prototype = new Person(); //3
1 つ目は、上で述べたように、このように直接記述すると、サブクラスと基本クラスが同時に bosn インスタンスを指すようになります。
2 番目のメソッドはこの点を回避し、継承を適切に実装し、インスタンスが最初にサブクラスをクエリし、対応する属性がない場合は基本クラスをクエリします。
3 番目の型も継承が実装されていますが、この例では、コンストラクターには name と age という 2 つのパラメーターがありますが、この 3 番目の型は何も渡さず、インスタンス化されません。
以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。