TIL 57 day第6章プロトタイプ
5463 ワード
プロトタイプ
:オブジェクトをプロトタイプ(prototype)としてコピー(参照)し、継承と同様の効果
コンセプト(コンストラクション関数、プロトタイプ、インスタンス)
var instance = new Constructor();
=>インスタンスは、非表示のProperty
__proto__
を介してこれらのメソッドにアクセスすることもできます.※
instance.__proto__
方式では直接アクセスできません=>ブラウザの互換性をサポートしていますが、推奨されていませんObject.getPrototypeOf(instance)
/24579142でvar Person = function(name){
this.name = name;
}
Person.prototype.getName = function() {
return this._name;
}
var suzi = new Person('suzi');
suzi.__proto__.getName(); // undefined (error 나지 않음)
Person.prototype === suzi.__proto__ // true
=>
Refelect.getPrototypeOf(instance)
ではなく、suzi
という名前のオブジェクトです.=>
suzi.__proto__
は省略可能なpropertyである.suzi.__proto__.getName
=> suzi(.__proto__).getName
=> suzi.getName
コンストラクション関数のprototypeに何らかのメソッドまたはpropertyがある場合、インスタンスは独自のようにメソッドまたはpropertyにアクセスすることもできます.var Constructor = function (name) {
this.name = name;
}
Constructor.prototype.method1 = function(){};
Constructor.prototype.property1 = 'Constructor Prototype Property';
var instance = new Constructor('Instance');
console.dir(Constructor); // 1번
console.dir(instance); // 2번
2番が
__proto__
と出力されたのは、インスタンスがそのコンストラクション関数の名前をその関数のインスタンスとしてマークしているからです.var arr = [1, 2];
console.dir(arr);
console.dir(Array);
Contructor
はArrayである.リファレンスプロトタイプ=>
__proto__
省略可能=>インスタンスは、push、pop、forEachなどのメソッドを呼び出すように
インスタンスはfrom、isArrayなどのメソッドを直接呼び出すことはできません(
=>Arrayジェネレータ関数から
コンストラクタ
=>オリジナルコンストラクション関数(自己)を参照
=>これはインスタンスからそのプロトタイプが何であるかを知る手段である.
var arr = [1,2];
Array.prototype.constructor === Array // true
arr.__proto__.constructor === Array // true
arr.constructor === Array //true
var arr2 = new arr.constructor(3, 4);
console.log(arr2); // [3, 4]
=>コンストラクション関数propertyに依存してインスタンスのコンストラクション関数情報を取得することは、必ずしも安全ではありません.
[Constructor]
[instance].__proto__.constructor
[instance].constructor
Object.getPrototypeOf([instance]).constructor
[Constructor].prototype.constructor
[Constructor].prototype
[instance].__proto__
[instance]
Object.getPrototypeOf([instance])
プロトタイプチェーン
1)メソッドオーバーフロー
var Person = function(name) {
this.name = name;
};
Person.prototype.getName = function() {
return this.name;
};
var iu = new Person('지금');
iu.getName = function() {
return '바로 ' + this.name;
}
console.log(iu.getName()); // 바로 지금
呼び出されたのはiuオブジェクト上のgetNameメソッドで、__proto__
ではありません.=>メソッドオーバーライド
:
iu.__proto__.getName
=>thisはprototypeオブジェクト(console.log(iu.__proto__.getName()); // undefined
)を指します.prototypeにname propertyがないため、prototypeにname propertyがある場合、この値が出力されます.一般的に、メソッドオーバーライドであれば、自分に最も近いメソッドにしかアクセスできませんが、自分に最も近い
iu.__prototype
にもアクセスできます.2)プロトタイプチェーン
__proto__
は、オブジェクトを含む.プロトタイプ接続var arr = [1, 2];
arr(.__proto__).push(3);
arr(.__proto__)(.__proto__).hasOwnProperty(2); //true
__proto__
プロトコルにおいて、__proto__
プロトコルはまたvar arr = [1, 2];
Array.prototype.toString.call(arr); // 1, 2
Object.prototype.toString.call(arr); // [object Array]
arr.toString(); // 1, 2
arr.toString = function() {
return this.join('_');
};
arr.toString(); //1_2
3)対象メソッドのみの例外
__proto__
は常にプロトタイプチェーンの最上位に存在します.参照型データだけでなく、基本型データもObject.prototype
に繰り返しアクセスでき、最終的に対象となる.原型に近づくことができるからです.=>オブジェクトにのみ機能する専用メソッドはObjectです.スタティックメソッド(static method)で原型ではないオブジェクトを付与するしかありません!
4)マルチプロトコルチェーン
var Grade = function() {
var args = Array.prototype.slice.call(arguments);
for (var i = 0; i <args.length; i++) {
this[i] = args[i]
}
this.length = args.length;
};
var g = new Grade(100, 80);
Grade.prototype = [];
console.log(g);
g.pop();
console.log(g);
g.push(90);
console.log(g);
アレイのようなオブジェクト=>
__proto__
、すなわちGrade.Prototypeに配列のインスタンスを表示させるとよい.Reference
この問題について(TIL 57 day第6章プロトタイプ), 我々は、より多くの情報をここで見つけました https://velog.io/@winney_77/TIL-57-day-6장-프로토타입テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol