この記事では、JavaScript のプロトタイプ オブジェクトに関する関連知識を提供します。お役に立てば幸いです。
# 授業は理解できましたか?授業の特徴は何ですか? (カプセル化、継承、ポリモーフィズム)
クラスは実際には「特別な関数」です。定義できる関数式や関数宣言と同様に、クラス構文も 2 つのコンポーネントで構成されます。クラス宣言とクラス式。クラスの本体は厳密モードで実行されます。 クラスのクラス本体は、中括弧 {} で囲まれた部分であり、クラスのメンバーが定義されます。 [メンバーは主にメソッドまたはコンストラクターです]クラスのすべてのメソッドは、クラスのプロトタイプ属性で定義されているのと同じです。クラスのインスタンスでメソッドを呼び出すことは、プロトタイプでメソッドを呼び出すことと同じです。class A(){ constructor(){} a(){} b(){} } //等价于 A.prototype={constructor(){},a(){},b(){}}
class Rectangle{ constructor(height,width){ this.height=height; this.width=width; } }
を使用します。 注: 関数宣言とクラス宣言の違い: クラス宣言は昇格されず、関数宣言は昇格されます。
クラス式: クラス式には名前を付けることも匿名にすることもできます。名前付きクラス式に与えられた名前は、クラス本体のローカル名です。let Rectangle=class{//匿名类 constructor(height,width){ this.height=height; this.width=width; } } let Rectangle= class Rectangle{//命名类 constructor(height,width){ this.height=height; this.width=width; } }
スーパー クラスの特性class:
- カプセル化: 主に関数を通じて、プライベート プロパティとメソッドの設定は主にブロック レベルのスコープを通じて実現されます - ポリモーフィズム: 関数を通じて呼び出すことができますなぜなら、パラメーターは変更可能であるためです。コンストラクターのプロトタイプ属性 (プライベート フィールド [[プロトタイプ]] との違いに注意してください) をプロトタイプとして使用して、新しいオブジェクトを作成します。 これと呼び出しパラメータをコンストラクターに渡して実行します;
コンストラクターがオブジェクトを返す場合はそれを返し、それ以外の場合は最初のステップで作成したオブジェクトを返します。
new の後の関数名は大文字にする必要がありますか?
ProtoType を理解するには? オブジェクトの特定の属性を見つけるプロセス?
プロトタイプ:各関数には、プロトタイプ オブジェクトと呼ばれる特別な属性があります。[プロトタイプ]js は In に基づいています。プロトタイプ言語の場合、各オブジェクトにはプロトタイプ オブジェクトがあり、オブジェクトはそのプロトタイプをテンプレートとして使用し、プロトタイプからメソッドとプロパティを継承します。これらのプロパティとメソッドは、オブジェクト インスタンス自体ではなく、オブジェクトのコンストラクターの上のプロトタイプ属性で定義されます。
プロトタイプ オブジェクトはプロトタイプ オブジェクトを持つことができ、オブジェクトのプロトタイプ オブジェクトが null になるまで、レイヤーごとに、プロトタイプ オブジェクトからメソッドとプロパティを継承できます。これがプロトタイプ チェーンです。 オブジェクト インスタンスを作成すると、オブジェクト インスタンスとそのコンストラクター [__proto__ 属性。コンストラクターのプロトタイプ属性から派生します。つまり、__proto__ とコンストラクターのプロトタイプは同じオブジェクトを指します。] Object.getPrototypeof(new Foobar()) と Foobar.prototype は等しいです。
Object.create()。指定されたプロトタイプ オブジェクトから新しいオブジェクトを作成します。 var newObj=Object.create(obj)。次に、 newObj の __proto__=obj
実際の各列オブジェクトは、プロトタイプからコンストラクター属性を継承します。このプロパティは、このインスタンスを構築するコンストラクターを指します。
一般に、属性はコンストラクターで定義され、メソッドはプロトタイプで定義されます。
一般由构造函数实列化出一个新对象,新对象的原型对象是一个constructor和一个Object的原型对象组成。而函数构造函数的原型对象是也是由另外一个constructor和一个Function的原型对象组成。
var F=function(){}; Object.prototype.a=function(){}; Function.prototype.b=function(){}; var f=new F(); //上面的结果是,f能取到a,不能取到b. 详解: 1.f.__proto__===F.prototype 2.F.prototype.__proto__===Object.prototype(所以f可以访问a) 3.f.constructor===F 4.F.__proto__===Function.prototype(所以f.constructor.b可以访问)
查找属性的过程:
1.先查找自己身属性是否由包含该属性。
2.如果没有,才会沿着原型链,层层向上搜索,直到找到名字的属性
3.如果找到最后原型链的末尾,即最后的原型为null,那就是没有找到该属性。就会返回undefined
不同方法创建对象和原型链
1.使用语法结构创建对象
var o = {a: 1}; // o 这个对象继承了 Object.prototype 上面的所有属性 // o 自身没有名为 hasOwnProperty 的属性 // hasOwnProperty 是 Object.prototype 的属性 // 因此 o 继承了 Object.prototype 的 hasOwnProperty // Object.prototype 的原型为 null // 原型链如下: // o ---> Object.prototype ---> null var a = ["yo", "whadup", "?"]; // 数组都继承于 Array.prototype // (Array.prototype 中包含 indexOf, forEach 等方法) // 原型链如下: // a ---> Array.prototype ---> Object.prototype ---> null function f(){ return 2; } // 函数都继承于 Function.prototype // (Function.prototype 中包含 call, bind等方法) // 原型链如下: // f ---> Function.prototype ---> Object.prototype ---> null
2.使用构造函数创建对象
function A() { this.a = 1; this.b = 2; } A.prototype = { write: function(){ console.log(this.a); } }; var a = new A(); // a 是生成的对象,他的自身属性有 'a' 和 'b'。
3.使用Object.create()创建对象(ES5)
var a = {a: 1}; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(b.a); // 1 (继承而来) var c = Object.create(b); // c ---> b ---> a ---> Object.prototype ---> null var d = Object.create(null); // d ---> null console.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype 使用
4.使用class创建对象(ES6)
class A { constructor(a, b) { this.a = a; this.b = b; } } class B extends A { constructor(a,b,c) { super(a, b); this.c=c; } get ab() { return this.a + this.b; } set d(d) { this.a = d; this.b = d; this.c = d; } } var a= new A('a','b');//a的原型对象是 A.prototype var b = new B('a','b','c');// //b的原型对象是 B.prototype
当一个对象设置属性时都发生了什么?
如果对象包含普通数据访问属性,直接赋值只会修改属性值
var a={b=1}//因为b是a的普通属性,数据类型为Number
a.b="a"; //直接更改b的类型为String,且赋值为'a'.
如果对象找不到该属性,且原型链也找不到,就直接默认添加一个属性到该对象上。
var a={}//b不是a的普通属性,且原型链上也没有
a.b="a"; //直接在a上添加b的类型,为String,且赋值为'a'.
如果属性b,存在于原型链上
//在原型链上层存在名为b的普通数据访问属性并且没有标记为只读(writable:false),那就会直接在a中添加一个名为b的新属性,且值为'a'。而原型链上的b就会被屏蔽掉:
function A(){}; A.prototype.b=1; var a=new A(); a.b='a';
//在原型链上层存在b,但是他被标记为只读,那么无法修改已有属性,或者在a中创建屏蔽属性。如果运行在严格模式下,代码会抛出一个错误,否则,这条赋值语句会被忽略,总之,不会发生屏蔽。
function A(){ }; A.prototype.b=1 Object.defineProperty(A.prototype,'b',{ configurable:true, writable:false }) var a=new A(); a.b='a';//结果a.b还是1
【相关推荐:javascript学习教程】
以上がプロトタイプオブジェクトのJavaScript学習まとめ(整理・共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。