本日はJavascript オフジェクト&配列の応用です。そして今日から復習も開始。朝起きたら3日分くらいの記事を軽く読むようにします。HPに応用できるコードをもっと見つけたい!
初めての人はお金持ちまでの道のり:0日目をまず読んでみてください!よろしくお願いします★
Javascript オブジェクト&配列の応用
13. オブジェクトの基礎の復習~応用
オブジェクトとは?
オブジェクトは、プロパティ(値)とメソッド(関数)を持つデータの集まりです。オブジェクトを使うことで、複数の関連データを1つにまとめ、扱いやすくすることができます。
※データ(プロパティ)、動作(メソッド)
let person = {
name: "John",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
・nameとageはプロパティ(オブジェクトの持つ値)
・greetはメソッド(関数)
※データ(プロパティ)、動作(メソッド)
※name, ageがプロパティ、john, 30がその値。greetがメソッド、functionはその関数
※このgreet
も広義では「プロパティ」ですが、関数であることから、通常「メソッド」と呼ばれる
プロパティのアクセス
ドット表記(dot notation)
メリット
・簡潔で読みやすい。
・オブジェクトのプロパティ名が有効な識別子(英数字、アンダースコア、またはドル記号)であり、固定の名前の場合に適しています。
※できないことが結構ある(ブラケット表記のメリットにある3項目は全てできない)
let person = {
name: "John",
age: 30
};
console.log(person.name); // "John"
console.log(person.age); // 30
使用すべき状況:
・プロパティ名が固定であり、英数字やアンダースコア(_)、ドル記号($)などを使用する場合。
・コードをシンプルで直感的に書きたい場合。
ブラケット表記(bracket notation)
メリット
・プロパティ名を動的に決定できる(変数を使ってプロパティ名を指定できる)。
・無効な識別子(スペースや特殊文字を含むプロパティ名、数値で始まるプロパティ名など)に対応できる。
・プロパティ名が文字列や変数として扱われる。
※上記の3項目はドット表記ではできない
※ドット表記でできることはブラケット表記で全てできる
let person = {
"full name": "John Doe",
age: 30
};
console.log(person["full name"]); // "John Doe"
// 変数を使ってプロパティ名を指定する
let propertyName = "age";
console.log(person[propertyName]); // 30
使用すべき状況
・プロパティ名が動的に決まる場合(たとえば、変数としてプロパティ名を渡す場合)。
・無効な識別子を含むプロパティ名を扱う場合(たとえば、スペースやハイフンを含む名前)。
・プロパティ名に数値や特殊文字が含まれている場合。
注意点
・"John Doe", // "full name"にはスペースがあるのでクォーテーションが必要
・let propertyName = "age"; // ここでは"age"を文字列として扱うため、クォーテーションが必要
→変数でプロパティ名を動的に指定する場合、クォーテーションは必要です。なぜなら、変数は文字列を保持するので、その文字列がプロパティ名として使われます。
注意点をまとめると
①プロパティ名にクォーテーションが必要な場合:
スペースや特殊文字が含まれる場合、プロパティ名を文字列として扱うため、クォーテーションが必要です。
②プロパティ名にクォーテーションが不要な場合:
英数字のみで構成されたプロパティ名の場合、クォーテーションは不要です。
③変数でプロパティ名を指定する場合:
変数にはプロパティ名を文字列として代入するため、クォーテーションが必要です。
まとめ
・ドット表記は簡潔で読みやすく、プロパティ名が固定でシンプルなときに使用します。
・ブラケット表記は、プロパティ名が動的に変わる場合や特殊な名前を使用する必要がある場合に使用します。
メソッドの呼び出し
オブジェクト内のメソッドは、他のプロパティやメソッドにアクセスして動作を行うことができます。this
キーワードを使って、オブジェクト内のプロパティにアクセスします。
thisキーワード
let person = {
name: "John",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet(); // "Hello, my name is John"
this
を使うことで、同じメソッドがどのオブジェクトに属しているかに関係なく、そのオブジェクトのプロパティにアクセスできるようになります。たとえば、複数のオブジェクトで同じメソッドを使っても、this
を使えば、それぞれのオブジェクトに応じたプロパティを取得することが可能です。
this
がオブジェクトによって変わる
let person1 = {
name: "John",
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
let person2 = {
name: "Jane",
greet: person1.greet // 同じメソッドをperson2にも使用
};
person1.greet(); // "Hello, my name is John"
person2.greet(); // "Hello, my name is Jane"
この例では、person1
とperson2
が同じgreet
メソッドを共有していますが、this
によって、呼び出したオブジェクト(person1
またはperson2
)に応じたname
が参照されます。
このコードにageを加えた場合
let person1 = {
name: "John",
age: 20,
greet1: function() {
console.log("Hello, my name is " + this.name);
},
greet2: function() {
console.log("Hello, I am " + this.age);
}};
let person2 = {
name: "Jane",
age: 35,
greet1: person1.greet1, // 同じメソッドをperson2にも使用
greet2: person1.greet2 // 同じメソッドをperson2にも使用
};
person1.greet2(); // "Hello, I am 20"
person2.greet2(); // "Hello, I am 35"
・person1.greet2()が呼び出されると、thisはperson1を指すため、person1のageである20が表示されます。
・同様に、person2.greet2()が呼び出されると、thisはperson2を指すため、person2のageである35が表示されます。
3人になった場合
// person1 の定義
let person1 = {
name: "John",
age: 20,
greet1: function() {
console.log("Hello, my name is " + this.name);
},
greet2: function() {
console.log("Hello, I am " + this.age);
}
};
// person2 の定義
let person2 = {
name: "Jane",
age: 35,
greet1: person1.greet1, // person1 の greet1 を共有
greet2: person1.greet2 // person1 の greet2 を共有
};
// person3 の定義
let person3 = {
name: "Mike",
age: 40,
greet1: person1.greet1, // person1 の greet1 を共有
greet2: person1.greet2 // person1 の greet2 を共有
};
// 各人の greet メソッドを呼び出す
person1.greet2(); // "Hello, I am 20"
person2.greet2(); // "Hello, I am 35"
person3.greet2(); // "Hello, I am 40"
3人以上の場合は配列の方がいい
// 3人のデータをオブジェクトとして配列にまとめる
let people = [
{
name: "John",
age: 20,
greet1: function() {
console.log("Hello, my name is " + this.name);
},
greet2: function() {
console.log("Hello, I am " + this.age);
}
},
{
name: "Jane",
age: 35,
greet1: function() {
console.log("Hello, my name is " + this.name);
},
greet2: function() {
console.log("Hello, I am " + this.age);
}
},
{
name: "Mike",
age: 40,
greet1: function() {
console.log("Hello, my name is " + this.name);
},
greet2: function() {
console.log("Hello, I am " + this.age);
}
}
];
// forEach で各人の greet2 を呼び出す
people.forEach(function(person) {
person.greet2();
});
このコードの説明
配列 people:
3人のデータ(nameとage)をそれぞれオブジェクトとしてまとめ、配列peopleに格納しています。
各オブジェクトには、それぞれのgreet1とgreet2メソッドも含まれています。
forEach()を使った繰り返し処理:
配列peopleに対してforEach()メソッドを使い、各人のgreet2()メソッドを順番に呼び出しています。
これにより、コードが簡潔でスッキリした形になります。
配列を使うべき理由
・複数のオブジェクトを一括で処理できるため、コードが整理され、読みやすくなります。
・forEach()やmap()などの配列メソッドを使うことで、ループ処理が簡単に書けます。
・配列を使うと、オブジェクトの数が増えても管理しやすくなります。
まとめ
・3人以上のオブジェクトを扱う場合は、配列を使うことでコードが整理され、簡潔になります。
・配列メソッドを活用すると、効率的にオブジェクトを処理できるため、拡張性が高いです。
オブジェクトの応用
実際の開発では、オブジェクトを使って複雑なデータ構造を作成したり、複数のデータを簡単に管理できます。たとえば、複数のユーザーを管理する場合は、オブジェクトの配列を使うことがよくあります。
let users = [ //[]内は配列
{ name: "John", age: 30 }, //{}内はオブジェクト
{ name: "Jane", age: 25 },
{ name: "Mike", age: 35 }
];
console.log(users[1].name); // "Jane"
・配列は自動的に0から順番にインデックス番号が割り当てられるので、John, Jane, Mikeにそれぞれ0, 1, 2のインデックス番号が割り当てられている。
・配列には[]
(ブラケット)を使う。
・[]
(ブラケット)の要素が文字列のみの場合は、""
(ダブルクォーテーション)や''
(シングルクォーテーション)で文字列を囲んでリストを作る。
・オブジェクトを定義する際には、{}
(波括弧)を使い、プロパティ名とその値をセットで定義する。
14. 配列の応用(+基礎の復習)
配列の基本
配列は複数のデータを1つの変数に格納できるデータ構造です。配列の要素には、文字列、数値、オブジェクト、さらには他の配列も含めることができます。
let fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]); // "apple"(0番目の要素にアクセス)
配列の操作メソッド
push(): 配列の末尾に要素を追加
fruits.push("orange");
console.log(fruits); // ["apple", "banana", "cherry", "orange"]
"apple", "banana", "cherry", "orange"
pop(): 配列の末尾から要素を削除
fruits.pop();
console.log(fruits); // ["apple", "banana", "cherry"]
"apple", "banana", "cherry", "orange"
shift(): 配列の先頭から要素を削除
fruits.shift();
console.log(fruits); // ["banana", "cherry"]
"apple", "banana", "cherry"
unshift(): 配列の先頭に要素を追加
fruits.unshift("mango");
console.log(fruits); // ["mango", "banana", "cherry"]
"mango", "banana", "cherry"
slice(): 配列の一部を取り出す(新しい配列を作成)
// 元の配列を定義
let fruits = ["apple", "banana", "cherry", "orange"];
// slice() メソッドでインデックス 1 から 3 の手前までの要素を取得 つまり1から2まで
let citrus = fruits.slice(1, 3);
// 結果をコンソールに出力
console.log(citrus); // ["banana", "cherry"]
"apple", "banana", "cherry", "orange"
※「開始位置は含むが、終了位置は含まない」というルールはJavascriptやpythonのすべてのメソッドで適用されている。わかりにくいが慣れる必要あり。
→let citrus = fruits.slice(1, 3);
開始位置 1: インデックス1の要素("banana") から取り始めます。
終了位置 3: インデックス3の手前まで(つまりインデックス2まで)の要素を取り出します。
splice(): 配列の要素を削除・追加
let fruits = ["apple", "banana", "cherry", "orange"];
// インデックス1("banana")から始めて、2つの要素("banana"と"cherry")を削除し、その位置に"kiwi"と"grape"を追加
fruits.splice(1, 2, "kiwi", "grape");
console.log(fruits); // ["apple", "kiwi", "grape", "orange"]
・splice(1, 2, "kiwi", "grape")は、インデックス1("banana")から始めて、2つの要素("banana"と"cherry")を削除します。
・その削除された位置に、"kiwi"と"grape"を挿入します。
・splice()は、指定したインデックスから始めて、指定した数だけの要素を含んで削除します。つまり、インデックスに指定した要素は含まれます。
・slice()は、開始インデックスは含みますが、終了インデックスは含みません。つまり、「開始位置から終了位置の手前まで」の範囲を抽出します。
配列とループの組み合わせ
forループ
// 配列を定義
let fruits = ["mango", "kiwi", "grape", "cherry"];
// forループを使って配列のすべての要素を順番に出力
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 出力:
// mango
// kiwi
// grape
// cherry
●for (let i = 0; i < fruits.length; i++)
・forループは、繰り返し処理を行うための構文です。
・let i = 0: ループカウンタiを0からスタートします。これは、配列の最初の要素(インデックス0)から始めることを意味します。
・i < fruits.length: fruits.lengthは、配列fruitsの長さ(要素の数)を返します。このコードの要素数は4です。iが配列の長さに達するまで(i < fruits.length)ループを続けます。iはインデックス番号0からスタートするので(0のmangoから3のcherryまで)、要素数4を超えることはありません。
・i++: ループが1回実行されるたびに、iを1つずつ増やしていきます。つまり、次の要素に移動します。
●console.log(fruits[i]);
・fruits[i]は、インデックスiに対応するfruits配列の要素を指します。たとえば、i = 0の場合、fruits[0]は配列の最初の要素("mango")になります。
・console.log()は、その要素をコンソールに表示します。
※console.log(fruits[i]);のようにiを削除すると["mango", "kiwi", "grape", "cherry"]と出力される。iがあると箇条書きのように一つずつ改行されて出力される。
forEach()メソッド(配列専用のメソッド)
let fruits = ["mango", "kiwi", "grape", "cherry"];
fruits.forEach(function(fruit) {
console.log(fruit); // 各要素を1つずつ出力
});
// 出力:
// mango
// kiwi
// grape
// cherry
※forEach(function(…))のようにforEachとfunctionはセット
●各部分の説明
①fruits.forEach(function(fruit) {...})
・forEach()
メソッドは、配列fruits
の各要素に対して1度ずつ処理を行うためのメソッドです。
・function(fruit)
: forEach()
は、コールバック関数を受け取ります。この関数には、各要素が引数として渡されます。この例では、各要素がfruit
という引数として渡されます。
②console.log(fruit)
・**fruit
**は、fruits
配列の各要素です。forEach()
が順番に配列のすべての要素に対して処理を実行するので、それぞれのfruit
がconsole.log()
で出力されます。
・各要素が1つずつ改行して出力されます。
●ループの動作forEach()
がfruits
配列のすべての要素に対して以下のように処理を行います:
・最初の要素 "mango" が console.log(fruit) に渡され、表示されます。
・次に "kiwi" が渡され、表示されます。
・"grape" が渡され、表示されます。
・最後に "cherry" が渡され、表示されます。
★for
ループとforEach()
メソッドの違い
基本的な構造
・forループ: 手動でループ条件を設定する必要がある(初期化、条件、増加を記述)。
・forEach(): 配列専用のメソッドで、自動的に全要素に対して処理を実行。※forEach(function(…))のようにforEachとfunctionはセット
使える対象
・forループ: 任意のデータ型や回数の繰り返し処理が可能(配列に限らない)。
・forEach(): 配列専用のメソッド。
制御
・forループ: breakやcontinueを使ってループを途中で終了・スキップできる。
・forEach(): breakやcontinueは使えない(途中でループを抜けることができない)。
パフォーマンス
・forループ: シンプルな繰り返し処理として最適。パフォーマンスも高い。
・forEach(): 処理が直感的で簡単だが、forループに比べて若干遅いことがある。
可読性
・forループ: 手動で条件を書く必要があるため、やや複雑に見えることがある。
・forEach(): コードがシンプルで可読性が高い。特に配列に対する処理が簡潔。
配列の応用例
let users = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Mike", age: 35 }
];
users.forEach(function(user) {
console.log(user.name + " is " + user.age + " years old.");
});
// 出力:
// "John is 30 years old."
// "Jane is 25 years old."
// "Mike is 35 years old."
各部分の説明
users配列:
・usersはオブジェクトの配列で、各オブジェクトがnameとageという2つのプロパティを持っています。
・usersの中身は次の3つのオブジェクトです:
{ name: "John", age: 30 }
{ name: "Jane", age: 25 }
{ name: "Mike", age: 35 }
forEach()メソッド:
・forEach()は、配列の各要素に対して1回ずつコールバック関数を実行するためのメソッドです。
・この場合、配列usersの各要素(ユーザーオブジェクト)に対して、順番に処理を行います。
コールバック関数:
・function(user)は、forEach()が処理するたびに、users配列の各要素(ユーザーオブジェクト)をuserとして渡します。
・console.log(user.name + " is " + user.age + " years old.");では、各ユーザーのnameとageを文字列として組み合わせ、コンソールに出力します。
★このコードの利点
・シンプルで直感的: 配列usersの要素に対してforEach()で繰り返し処理を行い、各オブジェクトのプロパティにアクセスして出力しています。
・配列専用のforEach()メソッドを使うことで、コードが短くわかりやすくなっています。
配列の高度な応用
map(): 配列を基に新しい配列を作る
let numbers = [1, 2, 3, 4];
let doubled = numbers.map(function(number) {
return number * 2;
});
console.log(doubled); // [2, 4, 6, 8]
numbers配列:
・numbersは、[1, 2, 3, 4]という数値を含む配列です。
map()メソッド:
・map()メソッドは、配列の各要素に対して指定された関数(コールバック関数)を実行し、その結果を新しい配列として返します。
・map()は元の配列を変更せず、常に新しい配列を生成します。
コールバック関数:
・function(number)という匿名関数が、map()によって配列の各要素に適用されます。
・この場合、各numberを2倍にして、その結果を返しています(return number * 2)。
・map()は、返された値を新しい配列に格納します。
doubled配列:
・map()の結果として、新しい配列doubledが作成されます。
・元のnumbers配列の各要素を2倍にした値が格納され、doubledには[2, 4, 6, 8]という新しい配列が入ります。
filter(): 条件に合う要素だけを抽出
let users = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Mike", age: 35 }
];
let adults = users.filter(function(user) {
return user.age >= 30;
});
console.log(adults); // [{name: "John", age: 30}, {name: "Mike", age: 35}]
users
配列:
users
は、3つのオブジェクトを含む配列です。各オブジェクトには、name
とage
というプロパティが含まれています。- 例:
{ name: "John", age: 30 }
,{ name: "Jane", age: 25 }
,{ name: "Mike", age: 35 }
filter()
メソッド:
filter()
メソッドは、配列の各要素に対して指定された条件をテストし、その条件に合致する要素だけを新しい配列として返すメソッドです。- 元の配列は変更せず、条件に合う要素だけを含む新しい配列が返されます。
コールバック関数:
function(user)
は、配列の各要素(ユーザーオブジェクト)に適用され、user.age >= 30
という条件をチェックします。return user.age >= 30;
では、ユーザーの年齢が30
以上の場合にtrue
を返し、true
を返した要素だけが新しい配列に含まれます。
adults
配列:
filter()
の結果として、user.age >= 30
を満たすユーザーだけが新しい配列adults
に含まれます。- この場合、
John
(30歳)とMike
(35歳)が条件を満たしているので、adults
にはその2つのオブジェクトが含まれます。
reduce(): 配列を1つの値にまとめる
let numbers = [1, 2, 3, 4];
let sum = numbers.reduce(function(total, number) {
return total + number;
}, 0);
console.log(sum); // 10
numbers
配列:
numbers
は[1, 2, 3, 4]
という数値を含む配列です。
reduce()
メソッド:
reduce()
は、配列の各要素に対して累積処理を行い、**1つの値(ここでは合計)**を返すメソッドです。reduce()
メソッドは、2つの引数を受け取るコールバック関数と、累積処理の開始値(ここでは0
)を取ります。reduce()
は、配列の要素を1つの結果にまとめるためのメソッドで、「縮約」や「集約」というイメージです。- 「減らす」意味ではなく、累積的な処理を行い、結果を1つにまとめる操作を行うことから「reduce」と呼ばれています。
- 累積処理の内容は、足し算、掛け算、最大値の取得など、さまざまなものに応用できます。
コールバック関数:
function(total, number)
では、total
は前回の累積結果、number
は現在の配列の要素です。
→total
とnumber
は、変数であり、好きな名前に変更することが可能return total + number;
は、現在の累積結果にnumber
を加算し、次のイテレーションでtotal
として渡されます。
※ループ処理や再帰処理などで、同じ処理が複数回繰り返されるとき、その1回ごとの処理をイテレーションと言います。
初期値 0
:
reduce()
の第2引数として0
が指定されています。これは累積処理の初期値で、最初のtotal
にセットされます。
※これは何番目の要素なのかを指すためのものではない。インデックス番号とは違う。ただの初期値。初期値を入力しない場合、初期値は1番目の数字になり、計算に使われる数字は2番目のものからになる。
sum
:
reduce()
が全ての配列の要素に対して累積処理を終えると、最終的な合計値が返され、それがsum
に格納されます。- この場合、
sum
には配列numbers
の合計10
が格納されます。
★役立つ配列メソッド(未学習のメソッドも含まれています)
map()
: 配列の各要素を変換し、新しい配列を作成する。
- 例:
[1, 2, 3].map(x => x * 2)
→[2, 4, 6]
filter()
: 条件を満たす要素のみを抽出して新しい配列を作成する。
- 例:
[1, 2, 3, 4].filter(x => x > 2)
→[3, 4]
reduce()
: 配列のすべての要素を累積的に処理し、1つの結果にまとめる。
- 例:
[1, 2, 3, 4].reduce((total, x) => total + x, 0)
→10
slice()
: 指定した範囲の要素を抜き出して新しい配列を作成する。
- 例:
[1, 2, 3, 4].slice(1, 3)
→[2, 3]
splice()
: 配列の要素を削除・置き換え・追加する(元の配列を変更)。
- 例:
[1, 2, 3].splice(1, 1, "new")
→["1", "new", "3"]
forEach()
: 配列の各要素に対して指定された関数を1度ずつ実行する。
- 例:
[1, 2, 3].forEach(x => console.log(x))
find()
: 条件に合う最初の要素を返す。
- 例:
[1, 2, 3].find(x => x > 1)
→2
some()
: 配列の中で条件に合う要素が**1つでもあればtrue
**を返す。
- 例:
[1, 2, 3].some(x => x > 2)
→true
every()
: 配列のすべての要素が条件を満たせばtrue
を返す。
- 例:
[1, 2, 3].every(x => x > 0)
→true
concat()
: 2つ以上の配列を結合して新しい配列を作成する。
- 例:
[1, 2].concat([3, 4])
→[1, 2, 3, 4]
Javascript オブジェクトと配列の組み合わせ
オブジェクトの例
let 猫 = {
名前: "タマ",
年齢: 2,
色: "黒"
};
オブジェクトは、いろいろな情報をまとめて管理するための「入れ物」です。例えば、「猫」というオブジェクトには、名前、年齢、色などの情報を一緒に入れておけます。この場合、「名前」「年齢」「色」がオブジェクトの中に入っている情報です。{}を使います。
配列の例
let 好きな食べ物 = ["りんご", "バナナ", "スイカ"];
配列は、いくつかの情報を順番に並べたリストです。例えば、「好きな食べ物」という配列には、いろいろな食べ物を順番に並べられます。[]を使います。
配列の中にオブジェクトを入れる場合
let 猫たち = [
{ 名前: "タマ", 年齢: 2, 色: "黒" },
{ 名前: "ミケ", 年齢: 1, 色: "三毛" },
{ 名前: "クロ", 年齢: 3, 色: "黒" }
];
猫たち
という配列の中には、3匹の猫の情報がオブジェクトとして並んでいます。それぞれの猫が名前、年齢、色の情報を持っています。
オブジェクトの中に配列を入れる場合
let タマ = {
名前: "タマ",
年齢: 2,
色: "黒",
好きな食べ物: ["魚", "チキン", "かつお"]
};
タマという猫のオブジェクトに、「好きな食べ物」という配列が含まれています。これでタマが好きな食べ物を複数記録できます。
組み合わせの活用
オブジェクトと配列を組み合わせることで、たくさんの情報を効率よくまとめて管理できるようになります。例えば、クラスの全員の名前と好きな科目をまとめたり、動物園のすべての動物の情報を管理したりできます。
・配列の中にオブジェクトを入れると、たくさんのものを一度に管理できます(例えば、たくさんの猫)。
・オブジェクトの中に配列を入れると、1つのものに複数の関連情報を持たせることができます(例えば、1匹の猫の好きな食べ物リスト)。
脳がオーバーヒートしている感じがします。でも負けない。。。「Javascript オブジェクトと配列の組み合わせ」は12日目からこっちに移動させました。12日目の主な内容がToDoリストアプリを作成することなので。
10日目の記事はこちら
JavaScript初級編part5 10日目 2024/10/16(お金持ちまでの道のり)
12-16日目の記事はこちら
ToDoリストアプリの作成 12-16日目 2024/10/18-22(お金持ちまでの道のり)
ここに初めて来た人はゼヒ0日目を読んでください。プログラミング知識0のおじさんがお金持ちになるまでのプランと熱い思いが載っています。私と一緒に運要素を排除したゴリゴリの脳筋プレイでお金持ちを目指しませんか?
0日目の記事はこちら
お金持ちまでの道のり:0日目
コメント