#はじめに
Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。
前回の記事
#目的
- 関数とオブジェクトについての理解を深める
#本題
###1.プロトタイプチェーン
プロトタイプを多重形成したもの
どういうことかコードで確認します。
####例1
前提として
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.hello = function() {
console.log('hello ' + this.name);
}
// インスタンス化
const bob = new Person('Bob', 18);
bob.hello();
上記の状態でコンソールにbobを入れると
実行結果.
bob
Person {name: 'Bob', age: 18}
さらにPersonの中身を確認すると
実行結果.
Person {name: 'Bob', age: 18}
age: 18
name: "Bob"
[[Prototype]]: Object
hello: ƒ ()
constructor: ƒ Person(name, age)
[[Prototype]]: Object
constructor: ƒ Object()
:
:
上記のようにPrototypeが多階層に連なっている状態をプロトタイプチェーンという
####例2
このような状態だとどのようなことがおこるのか
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.hello = function() {
// 下記の出力結果と混同しないように名前をつける
console.log("Person: hello" + this.name);
}
// もう一個プロトタイプを用意
Object.prototype.hello = function() {
console.log('Object: hello ' + this.name);
}
const bob = new Person('Bob', 18);
// 上記の状態で出力するともちろんPersonが呼ばれるようになる
bob.hello();
しかし、Personの方をコメントアウトすると
function Person(name, age) {
this.name = name;
this.age = age;
}
// Person.prototype.hello = function() {
// // 下記の出力結果と混同しないように名前をつける
// console.log("Person: hello" + this.name);
// }
// こっちのプロトタイプが呼ばれる
Object.prototype.hello = function() {
console.log('Object: hello ' + this.name);
}
const bob = new Person('Bob', 18);
// プロトタイプの階層の浅いものから探しにいく
// 今回は出力結果にPersonが見つからなかったので、次にObjectを探している
bob.hello();
実行結果.
bob
Person {name: 'Bob', age: 18}
age: 18
name: "Bob"
[[Prototype]]: Object
constructor: ƒ Person(name, age)
[[Prototype]]: Object
hello: ƒ () ← Objectの中にhelloを発見
優先順位の高いほうが呼ばれている
####例3
this.helloが関数内にあった場合
function Person(name, age) {
this.name = name;
this.age = age;
// this.helloに関数を入れる
this.hello = function() {
// 下記と区別するためにOwnPropertyを作成
console.log('OwnProperty: hello ' + this.name);
}
}
// Person.prototype.hello = function() {
// // 下記の出力結果と混同しないように名前をつける
// console.log("Person: hello" + this.name);
// }
Object.prototype.hello = function() {
console.log('Object: hello ' + this.name);
}
const bob = new Person('Bob', 18);
// この結果の出力はOwnProperty: hello Bobとなる
// 自身のプロパティでhelloが見つかったから
// 自分のプロパティ → コンストラクター関数のプロトタイプのメソッド → 他のプロトタイプへ、、、
// 最終的にはundefinedが返ってくる
bob.hello();
###2.hasOwnProperty と in
####hasOwnProperty とは
自分自身のオブジェクトのプロパティとして引数で与えた名前が存在するかどうかを確かめることができる
function Person(name, age) {
this.name = name;
this.age = age;
}
Object.prototype.hello = function() {
console.log('Object: hello ' + this.name);
}
const bob = new Person('Bob', 18);
// bobにnameプロパティが存在するかどうか引数に入れて確認
const result = bob.hasOwnProperty("age");
// trueと返ってくる
console.log(result);
// Objectのhelloメソッドを入れると
const result2 = bob.hasOwnProperty("hello");
// falseで返ってくる(あくまで自分自身のプロパティに対応)
console.log(result2);
in とは
function Person(name, age) {
this.name = name;
this.age = age;
}
Object.prototype.hello = function() {
console.log('Object: hello ' + this.name);
}
const bob = new Person('Bob', 18);
const result = bob.hasOwnProperty("age");
console.log(result);
// bobオブジェクトの中に"引数"に対応するプロパティはあるか確認できる
console.log("name" in bob);
// この場合プロトタイプチェーンも遡るので、trueと返ってくる
console.log("hello" in bob);
// もちろん存在しないものはfalse
console.log("bye" in bob);
// Objectのプロトタイプに格納されているhasOwnPropertyもプロトタイプチェーンによって格納されているのでtrue
console.log("hasOwnProperty" in bob);
- hasOwnPropertyは自分自身のプロパティのみ
- inはプロトタイプチェーンまで探す
今日はここまで!
#参考にさせて頂いた記事