JavaScript (基礎編)

  1. 事前準備
    1. VSCode のインストール
    2. Google Chrome のインストール
  2. 変数とは
    1. 数字を出力する
    2. 文字を出力する
    3. 値の再代入
    4. 変数同士で計算する
    5. 文字列を結合する
  3. 定数とは
    1. 文字列を出力する
    2. 値の再代入
  4. if 文 (分岐) とは
    1. 条件分岐
      1. 条件式
      2. データ型の変換
      3. 真偽値への変換
      4. 条件式の評価
      5. else if
    2. true の時だけ処理が実行される
    3. if 文のネスト
    4. 論理積 (AND) と論理和 (OR)
    5. 否定演算
  5. if-else 構文とは
    1. true の場合とそれ以外の場合
    2. 論理積 (AND) と論理和 (OR) の組み合わせ
    3. 比較演算
  6. for、while 文 (繰り返し) とは
    1. while 文
    2. for 文
      1. continue
      2. break
    3. 九九の出力
  7. 関数
    1. 関数宣言
      1. 宣言と呼び出し
      2. 引数
      3. 複数の引数
      4. 戻り値
      5. 別の例
    2. 関数式 (無名関数)
      1. 関数宣言と無名関数の比較
      2. 別の例
    3. アロー関数
      1. アロー関数と関数式の比較
      2. アロー関数の省略形 (戻り値のない関数)
      3. アロー関数の省略形 (戻り値のある関数)
      4. 別の例
    4. 関数の使い方
    5. 成績を 5 段階で評価
    6. max 関数との組み合わせ
  8. オブジェクト
    1. データの型
    2. オブジェクトの初期化 (作成)・参照・再代入
    3. テンプレートリテラルでのオブジェクトの出力
    4. オブジェクトと関数の組み合わせ
    5. オブジェクトのメソッド
    6. this
    7. メソッドを使ってテンプレートリテラルを実行
    8. オブジェクトを value としたプロパティ
  9. 配列 (Array) オブジェクト
    1. 配列の出力
    2. 配列の要素の書き換え
    3. length
    4. 配列のメソッド
      1. push
      2. slice
      3. concat
      4. map
      5. filter
      6. reduce
    5. 多次元配列
      1. 出力とアクセス
      2. 九九表の作成
    6. 特定の要素が含まれているか判定
    7. 素数を求める
  10. ミュータブルとイミュータブル
    1. ミュータブルの例
      1. オブジェクト
      2. 配列
    2. イミュータブルの例
    3. const と let
      1. const 定数は再代入できない
      2. let 変数は再代入可能
      3. const 定数でも内容 (値) は修正可能
  11. 破壊的メソッドと非破壊的メソッド
    1. 破壊的メソッド
    2. 非破壊的メソッド

事前準備

VSCode のインストール

プログラムを書くためのエディターをインストールします。

  1. Google の検索画面で「vscode」と入力し、検索結果より「Visual Studio Code – コードエディター」を選択します。
  2. 「今すぐダウンロード」をクリックします。
  3. Windows などの該当の OS を選択し、インストールファイルをダウンロードします。
  4. インストールファイルを実行し、ウィザードに従います。

Google Chrome のインストール

プログラムの実行結果を確認するため、chrome ブラウザをインストールします。

  1. Google の検索画面で「chrome」と入力し、検索結果より「今すぐChromeをダウンロード」を選択します。
  2. 「Chrome をダウンロード」をクリックします。
  3. インストールファイルがダウンロードされるので、実行します。

変数とは

変数・定数とはデータにあだ名をつける機能です。
主に以下の三段階で構成されています。
宣言・・・あだなを作ること
代入・・・あだなに対して値を紐づけること
参照・・・あだなにひもづいている値を使うこと

数字を出力する

let で x という変数(あだ名)を宣言し、値 1 を代入(紐づけ)します。

let x = 1; // let で x という変数を宣言し、値 1 を代入
console.log(x); // 変数の名前を書くことで変数を参照

console.logという関数に 1 を渡し、結果が参照(出力)されます。

Console 出力結果

1

以下のように書き換えます。

let x = 1;
console.log(x + 3);
console.log(1 + 3);

x には 1 が紐づいているため、結果は同じ値となります。

Console 出力結果

4
4

文字を出力する

let name = 'りんご';
console.log('好きな果物は' + name + 'です。' )
Console 出力結果

好きな果物はりんごです。

値の再代入

let name = 'りんご';
name = 'オレンジ'; // 値の再代入は let の宣言は不要

console.log(name);
Console 出力結果

オレンジ

変数同士で計算する

x、yの 2 つの変数を宣言し、計算することも可能です。

let x = 50;
let y = 10;
console.log(x + y);
console.log(x * y);
console.log(x * y / 2);
console.log(x % y); // x を y で割ったあまりで「剰余」という
Console 出力結果

60
500
250
0

文字列を結合する

let a = '明日は';
let b = '晴れるでしょう。';
console.log(a + b);
Console 出力結果

明日は晴れるでしょう。

定数とは

変数と基本的には同じです。
const で定数を宣言します。
変数と異なり、一度値を代入した後、別の値を再代入することはできません。

文字列を出力する

const city = '東京';
const kion = city + 'の気温は~度です。';
const jinko = city + 'の人口は~人です。';
const menseki = city + 'の面積は~平方キロメートルです。';

console.log(kion);
console.log(jinko);
console.log(menseki);
Console 出力結果

東京の気温は~度です。
東京の人口は~人です。
東京の面積は~平方キロメートルです。

値の再代入

const name = 'りんご';
name = 'オレンジ'; // const は再代入不可

console.log(name);
Console 出力結果

Uncaught TypeError: Assignment to constant variable.

const で変数宣言した場合は、値の再代入はできなくなります。
基本は const で、必要時のみ let を使うのが一般的です。

if 文 (分岐) とは

条件分岐

let x = 5;
if (x > 3) {
    console.log('x は 3 より大きいです。');
}
else {
    console.log('x は 3 より小さいです。');
}
Console 出力結果

x は 3 より大きいです。

変数 x の値 5 が 3 より大きいため、「x は 3 より大きいです。」と出力されています。
変数 x の値を 2 に変更すると「x は 3 より小さいです。」が出力されます。

条件式

計算式を実行し、答えを得ることを「式を評価する」と言います。
以下の数式で「1」、「2」はデータの型では「数値」で、「+」は「演算子」と呼ばれ、値に処理を加える記号です。つまり値と演算子の組み合わせが「式」ということになります。
1 + 2

式を評価すると新たな値を得るようになっています。

データ型の変換

const num = 1;
console.log(num);
console.log(typeof num); // 数値の 1

const str = num.toString(); // 数値を文字列に変換
console.log(num);
console.log(typeof str); // 文字列の 1
Console 出力結果

1
number
1
string

真偽値への変換

全ての値は真偽値に変換できます。
どのような値も true か false のどちらかで表すことができます。

true「false」とみなされる値以外すべて
false数字の「0」、「-0」
文字列の「””」、空文字
「null」、「undefined」、「NaN」、「false」

例えば、数字の 1 を真偽値に変換すると true になります。

条件式の評価

// true として評価
let x = 5;
if (x > 3) { // 正しいので条件式を評価すると true
    console.log('x は 3 より大きいです。'); // こちらが実行
}
else {
    console.log('x は 3 より小さいです。');
}

// false として評価
x = 2;
if (x > 3) { // 正しくないので条件式を評価すると false
    console.log('x は 3 より大きいです。'); 
}
else {
    console.log('x は 3 より小さいです。'); // こちらが実行
}
Console 出力結果

x は 3 より大きいです。
x は 3 より小さいです。

let x = 3;
if (x) { // true か false かを基準に判断される
    console.log('この式は正しいです。'); // こちらが実行
}
else {
    console.log('この式は間違っています。');
}
Console 出力結果

この式は正しいです。

数字の 3 は真偽値では true のため、正しいと評価されています。

else if

let x = 3;
if (x > 3) {
    console.log('x は 3 より大きいです。');
}
else if( x === 3 ){ // x = 3 は x(変数) に 3 を代入の意なのでイコールではない
    console.log('x は 3 です。') // true なので実行
}
else {
    console.log('x は 3 より小さいです。');
}
Console 出力結果

x は 3 です。

true の時だけ処理が実行される

const condition = true; // condition という定数を宣言し、true という値を代入

if(condition) { // condition は boolean 型の値なので true と false 2 種類しか値がない
    console.log('condition は true です。');
}
console.log('結果を出力。');

condition が true なので、if 文のブロック内は実行され、以下の文字列が出力されます。

Console 出力結果

condition は true です。
結果を出力。

false の場合は if 文のブロック内は実行されません。

以下も同様です。

const condition = true;

if(condition) {
    const x = 100;
    const y = 0.5 * x ** 2;

    console.log(y);
}

console.log('結果を出力。')
Console 出力結果

5000
結果を出力。

false の場合は if 文のブロック内は実行されません。

if 文のネスト

if 文の中に if 文を書くことも可能です。

const condition1 = true;
const condition2 = true;

if(condition1) {
    console.log('condition1 は true です。');
    
    // --------------入れ子開始
    if(condition2){
        console.log('condition2 も true です。');
    }
    // --------------入れ子終了
}

console.log('結果を出力。')
Console 出力結果

condition1 は true です。
condition2 も true です。
結果を出力。

condition1 が true であれば if ブロック内の condition1、condition2 が実行されます。

const condition1 = false;
const condition2 = true;

if(condition1) {
    console.log('condition1 は true です。');
    
    // --------------入れ子開始
    if(condition2){
        console.log('condition2 も true です。');
    }
    // --------------入れ子終了
}

console.log('結果を出力。')
Console 出力結果

結果を出力。

condition1 が fase の場合、if ブロック内の condition1、condition2 は実行されません (condition2 が true であっても)。
condition1 が true で condition2 が false の場合、if ブロック内の condition1 のみ実行されます。

論理積 (AND) と論理和 (OR)

論理積 (AND) は 「&&」で boolean 型の値を区切ります。

const sansu80 = true; // 算数80点以上
const kokugo80 = true; // 国語80点以上

if (sansu80 && kokugo80) { // 両方 true の時のみ実行される
    console.log('合格');
}
Console 出力結果

合格

両方 true の時だけ実行され、それ以外は実行されません。

論理和 (OR) は 「||」で boolean 型の値を区切ります。

const sansu80 = true; // 算数80点以上
const kokugo80 = false; // 国語80点以上

if (sansu80 || kokugo80) { // どちらか一方が true であれば実行される
    console.log('合格');
}
Console 出力結果

合格

どちらか一方が true であれば実行されます。
両方が false の場合は実行されません。

否定演算

「!」の後が false の場合に処理が実行されます。

const sansu80 = true; // 算数80点以上
const kokugo80 = false; // 国語80点以上

if (sansu80 && kokugo80) { // true の場合に実行される
    console.log('合格');
}
if(!(sansu80 && kokugo80)) { // false の場合に実行される
    console.log('不合格');
}
Console 出力結果

不合格

論理積 (AND) が false であるため、否定演算の処理が実行されています。

if-else 構文とは

true の場合とそれ以外の場合

const sansu80 = true; // 算数 80 点以上
const kokugo80 = true; // 国語 80 点以上

if (sansu80 && kokugo80) { // true であれば実行
    console.log('合格');
}
else {
    console.log('不合格'); // true 以外であれば実行
}
Console 出力結果

合格

論理積 (AND) が true の場合は if ブロック内が実行されます。

const sansu80 = false; // 算数 80 点以上
const kokugo80 = true; // 国語 80 点以上

if (sansu80 && kokugo80) { // true であれば実行
    console.log('合格');
}
else {
    console.log('不合格'); // true 以外であれば実行
}
Console 出力結果

不合格

論理積 (AND) が false の場合は else ブロック内が実行されます。

論理積 (AND) と論理和 (OR) の組み合わせ

const sansu80 = true; // 算数 80 点以上
const kokugo80 = true; // 国語 80 点以上

if (sansu80 && kokugo80) { // true であれば実行
    console.log('合格');
}
else if(sansu80 || kokugo80) { // true であれば実行
    console.log('再試験')
} 
else {
    console.log('不合格'); // true 以外であれば実行
}
Console 出力結果

合格

論理積 (AND) が true の場合、if ブロック内が実行されます。

const sansu80 = true; // 算数 80 点以上
const kokugo80 = false; // 国語 80 点以上

if (sansu80 && kokugo80) { // true であれば実行
    console.log('合格');
}
else if(sansu80 || kokugo80) { // true であれば実行
    console.log('再試験')
} 
else {
    console.log('不合格'); // true 以外であれば実行
}
Console 出力結果

再試験

論理積 (AND) が false で論理和 (OR) が true の場合、else if のブロックが実行されます。
論理積 (AND)、論理和 (OR) が いずれも false の場合、else のブロックが実行されます。

比較演算

const sansu = 85;
const kokugo = 83;

if(sansu > 80 && kokugo > 80) {
    console.log('合格');
}
else {
    console.log('不合格');
}
Console 出力結果

合格

定数に boolean 型を使用しないパターンです。
論理積 (AND) が true なので if のブロックが実行されます。論理積 (AND) が false の場合、else のブロックが実行されます。

for、while 文 (繰り返し) とは

while 文と for 文は基本的に同じ動作です。
処理が複雑な場合は while 文が適しているようです。

while 文

let x = 0; // x という変数を宣言。初期値として 0 を代入

while (x < 10) { // カッコの中は boolean 型の値で true である間、処理が繰り返される。
    console.log(`変数に代入された値は${x}です。`);
    x++; // 変数 x が 1 ずつ増加。インクリメントと言う
}
Console 出力結果

変数に代入された値は0です。
変数に代入された値は1です。
変数に代入された値は2です。
変数に代入された値は3です。
変数に代入された値は4です。
変数に代入された値は5です。
変数に代入された値は6です。
変数に代入された値は7です。
変数に代入された値は8です。
変数に代入された値は9です。

for 文

for (let x = 0; x < 10; x++) { // for(初期化処理;繰り返し条件式;更新処理)
    console.log(`変数に代入された値は${x}です。`);
}
Console 出力結果

変数に代入された値は0です。
変数に代入された値は1です。
変数に代入された値は2です。
変数に代入された値は3です。
変数に代入された値は4です。
変数に代入された値は5です。
変数に代入された値は6です。
変数に代入された値は7です。
変数に代入された値は8です。
変数に代入された値は9です。

while 文と同じ出力結果となりますが、記述方法が若干異なっています。
while 文の場合は以下の書き方となっています。

let x = 0; // 初期化処理

while (x < 10) { // ()内は繰り返し条件式
    console.log(`変数に代入された値は${x}です。`);
    x++; // 更新処理
}

continue

for (let x = 0; x < 10; x++) {
    if(x === 5) { // 値が 5 の場合
        continue; // for 文の中の処理が中断して次のループに入る
    }    
    console.log(`変数に代入された値は${x}です。`);    
}
Console 出力結果

変数に代入された値は0です。
変数に代入された値は1です。
変数に代入された値は2です。
変数に代入された値は3です。
変数に代入された値は4です。
変数に代入された値は6です。
変数に代入された値は7です。
変数に代入された値は8です。
変数に代入された値は9です。

continue は if 文が true の時に for 文の処理を中断し、次のループに入ります。
結果として「5」の出力がありません。

break

for (let x = 0; x < 10; x++) {
    if(x === 5) { // 値が 5 の場合
        break; // for 文の中の処理が中止される
    }    
    console.log(`変数に代入された値は${x}です。`);    
}
Console 出力結果

変数に代入された値は0です。
変数に代入された値は1です。
変数に代入された値は2です。
変数に代入された値は3です。
変数に代入された値は4です。

break は if 文が true の時に for 文の処理を中止します。
結果として「5」以降の出力がありません。

九九の出力

for(let x = 1; x < 10; x++){ // 9 まで (true であるまで) 繰り返す
    let row = ""; // 空文字で初期化
    
    for(let y = 1; y < 10; y++) { // x = 1 の場合、y が 1-9 まで繰り返される
        row += `${x * y} `; //「row = row + `${x * y} `;」と同じ。文字同士を結合
    }
    console.log(row);
}
Console 出力結果

1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

for 文がネストされています。
変数 x の for 文で、x = 1 の時、変数 y の for 文は 値 1-9 まで実行され、x = 2 のループに移ります。
変数 x の for 文で、x = 9 になった段階で終了となります。

関数

関数の使い方は以下 3 種類あります。

  • 宣言・・・関数を作る(アロー関数、関数式、関数宣言)
  • 参照・・・データとして関数を使う
  • 呼び出し・・・データを変換する

関数宣言

宣言と呼び出し

function myAlert() { // 関数宣言。function + 関数名
   console.log('こんにちは。');
   console.log('文字を出力します。');
}
myAlert(); // 関数の呼び出し
Console 出力結果

こんにちは。
文字を出力します。

関数宣言をしただけでは何も起こりません。
「関数の呼び出し」を行うことで、{}内の処理が実行されます。
「関数の呼び出し」はどこでも何度でも実行することができます。

引数

function myAlert(greeting) { // greeting という引数を定義
   console.log(greeting);   
}
myAlert('おはようございます。'); // 引数を指定して関数を呼び出す
myAlert('こんにちは。'); 
myAlert('こんばんは。'); 
Console 出力結果

おはようございます。
こんにちは。
こんばんは。

複数の引数

function myAlert(greeting,tenki) { // 引数を二つ定義
   console.log(greeting);
   console.log(tenki + 'ですね。');   
}
myAlert('おはようございます。','晴れ'); // 引数を二つ指定して関数を呼び出す
Console 出力結果

おはようございます。
晴れですね。

戻り値

関数を実行することで得られる値を戻り値といいます。

function myCalc(a,b) {
   return a + b; // return で戻り値を設定
   // a + b を戻り値として設定
}
console.log(myCalc(1,2));
Console 出力結果

3

別の例

function max(x,y) { // function の後に max という関数名を指定
    if(x < y) {
        return y; 
    }
    return x;
}

console.log(max(30,20));
Console 出力結果

30

function の後に max という関数名を指定し、引数 x,y を指定します。

関数式 (無名関数)

const myAlert = function() { // 関数名が省略されている
   // 変数 myAlert の中身として無名関数が代入されている
   console.log('こんにちは。');
   console.log('関数式サンプルです。');
}
myAlert(); // 関数宣言と同様の呼び出し方
// myAlert; では呼び出し不可
Console 出力結果

こんにちは。
関数式サンプルです。

下記は関数を表していいますが、関数名は指定されていません。→ 無名関数

無名関数
function(){
}

変数 myAlert の中身として無名関数が代入されている状態です。
変数を関数の名前代わりに使用することができます。→ 関数式とも呼ばれます。

関数宣言と無名関数の比較

// 関数宣言
function myCalc(a,b) { // 関数宣言
   return a + b;
}
console.log(myCalc(1,2));

// 無名関数
const myCalc1 = function(a,b) { // myCalc1 は無名関数を代入した変数
   return a + b;
}
console.log(myCalc1(1,2));
Console 出力結果

3
3

仕組み上の違いはほとんどありません。

別の例

const max = function(x,y) { // function で関数を定義
    if(x < y) {
        return y; 
    }
    return x;
}

console.log(max(30,20));
Console 出力結果

30

「2つの値の組み合わせ」から「大きい方の値」に変換する関数となっています。

アロー関数

関数式を効率的な書き方ができるように新しいルールが導入されました。
今後はアロー関数を使用することが推奨されています。

アロー関数と関数式の比較

// 関数式
const myAlert1 = function() {
   console.log('関数式の例です。');
}
myAlert1();

// アロー関数
const myAlert2 = () => {
   console.log('アロー関数の例です。');
}
myAlert2();
Console 出力結果

関数式の例です。
アロー関数の例です。

関数式の「function()」がアロー関数では「() =>」に変更されています。

アロー関数の省略形 (戻り値のない関数)

  • 引数が一つだけの場合、引数を囲むカッコを省略できる。
    (引数が二つ以上の場合は必要)
  • 関数の中身の処理が 1 行だけの場合、{} と「return」を省略できる。
// 関数式
const myAlert1 = function(message) { // 引数は message 一つ
   console.log(message); // 関数の処理は一行
}
myAlert1('関数式です。');

// アロー関数
const myAlert2 = (message) => {
   console.log(message);
}
myAlert2('アロー関数です。');

// アロー関数 (省略形)
const myAlert3 = message => console.log(message);
myAlert3('アロー関数省略形です。');
Console 出力結果

関数式です。
アロー関数です。
アロー関数省略形です。

アロー関数の省略形 (戻り値のある関数)

// 関数式
const myCalc1 = function(a) { // 引数は a 一つ
   return a * a; // 2 乗する関数
}
console.log(myCalc1(2));

// アロー関数
const myCalc2 = (a) => {
   return a * a; // 関数は一行
}
console.log(myCalc2(2));

// アロー関数 (省略形)
const myCalc3 = a => a * a;
console.log(myCalc3(2));
Console 出力結果

4
4
4

別の例

const max = (x,y) => { // max という定数を宣言し、アロー関数式を代入。
    if(x < y) { // y が x より大きければyを返す
        return y; // return は返値 (関数が値を変換した後の値)
    }
    return x; // 上記が true にならなかった場合、x を返す
}

console.log(typeof max); // max という定数のタイプは function (関数)
console.log(max(30,20)); // max の () 内に変換する前の値を指定

max = (x,y) の x と y は引数といい、2 つの値を受け取る max という名の関数となっています。
(console.log(max);で確認可能)
関数は決められたルールに従ってある値を別の値に変換しますが、x と y は変換される前の値です。
=> の後は関数のルールを決めます。ルールは値を変換するプログラムです。

Console 出力結果

function
30

「2つの値の組み合わせ」から「大きい方の値」に変換する関数となっています。

関数の使い方

const max = (x,y) => { 
    if(x < y) {
        return y;
    }
    return x;
}

console.log(max(30,20));
console.log(max(10,100));
console.log(max(2 * 8,5**2));
Console 出力結果

30
100
25

何度も同じ計算を行う場合、関数を使うと便利です。
何度も同じ処理を呼び出すことができます。

成績を 5 段階で評価

const seiseki = (tensu) => {
    if(tensu < 20) {
        return '評価 1';
    }
    else if(tensu < 40) {
        return '評価 2';
    }
    else if(tensu < 60) {
        return '評価 3';
    }
    else if(tensu < 80) {
        return '評価 4';
    }   
    else {
        return '評価 5';
    }
}

const type = seiseki(70); // ここに点数を入れる
console.log(type);
Console 出力結果

評価 4

「点数」を受け取り、文字列に変換する関数です。

max 関数との組み合わせ

const max = (x,y) => { 
    if(x < y) {
        return y;
    }
    return x;
}

const seiseki = (tensu) => {
    if(tensu < 20) {
        return '評価 1';
    }
    else if(tensu < 40) {
        return '評価 2';
    }
    else if(tensu < 60) {
        return '評価 3';
    }
    else if(tensu < 80) {
        return '評価 4';
    }   
    else {
        return '評価 5';
    }
}

const type = seiseki(max(35,55)); // max 関数に 35,55 を渡した返値を seiseki 関数に渡す
console.log(type);
Console 出力結果

評価 3

max 関数の返値は 55 なので、「評価 3」が返されます。

オブジェクト

データの型

プリミティブ型は以下 7 つの基本的なデータ型の総称です。
それ以上分割できない値であり、物質を構成する原子のような存在です。
プリミティブ型の値はイミュータブル (変化しない値) という性質を持っています。

  • Undefined
  • Null
  • Boolean
  • Nunber
  • Bigint
  • Synbol
  • String

JavaScript ではプリミティブでないものは全てオブジェクトになります。

以下よくつかうデータ型と console.log での出力結果になります。

// 数値 (number)
console.log(10);
console.log(10 + 10);
console.log(typeof 10)

// 文字列 (string)
console.log('文字列');
// クォテーションで挟むことで文字列として認識
console.log(typeof '文字列');

// 真偽値 (boolean)
console.log(true);
console.log(false);
console.log(typeof true);

// オブジェクト (object)
console.log({ color: '赤', size: 'M' });
console.log(typeof { color: '赤', size: 'M' });
Console 出力結果

10
20
number

文字列
string

TRUE
FALSE
boolean

{color: ‘赤’, size: ‘M’}
object

typeof はデータの種類の判定結果を出力します。

オブジェクトの初期化 (作成)・参照・再代入

const akiba = { // akiba という定数にオブジェクトを作って代入
name: '運用GP', // プロパティは「キー: value」のペアとなっている、name がキー、運用 GP が value
leader: '山田太郎',
mem1: '木村和夫'
}

console.log(akiba.leader) // 変数.プロパティ名で value にアクセス可能
console.log(akiba['leader']) // この書き方でもよい

akiba.manager = '松崎卓'; // プロパティの追加。更新も可能

console.log(akiba); 
Console 出力結果

山田太郎
山田太郎
{name: ‘運用GP’, leader: ‘山田太郎’, mem1: ‘木村和夫’, manager: ‘松崎卓’}

テンプレートリテラルでのオブジェクトの出力

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫'
}

console.log(`秋葉原グループ名は${akiba.name}ですリーダーは${akiba.leader},メンバーの一人は${akiba.mem1}です。`);
// テンプレートリテラル。バッククォートで定義する。オブジェクトを使った出力
Console 出力結果

秋葉原グループ名は運用 GP ですリーダーは山田太郎,メンバーの一人は木村和夫です。

オブジェクトと関数の組み合わせ

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫'
}

const ueno = {
    name: '運用 GP2 ',
    leader: '荒川庄司',
    mem1: '田中一郎'
}

const introduce = (unyo) => { // introduce という定数を宣言し、引数を unyo とする
    console.log(`グループ名は${unyo.name}ですリーダーは${unyo.leader},メンバーの一人は${unyo.mem1}です。`);
}
// 返値なしの関数

introduce(akiba); // akiba を引数として渡す
introduce(ueno); // ueno を引数として渡す
Console 出力結果

グループ名は運用 GP ですリーダーは山田太郎,メンバーの一人は木村和夫です。
グループ名は運用 GP2 ですリーダーは荒川庄司,メンバーの一人は田中一郎です。

オブジェクトのメソッド

関数は「値」なので、オブジェクトのプロパティ (value) に関数を使うことができます。
オブジェクトのプロパティに関数を使う場合、その関数をオブジェクトのメソッドと呼びます。
メソッドには基本的にアロー関数は使用しません。

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫',
    mem2: function(arg) { // mem2 というプロパティに関数を紐づける
        return '新人'; // どんな引数も「新人」の文字列に変換される
    }
}

const value = akiba.mem2('鈴木'); // 引数「鈴木」が arg に渡される
console.log(value);
Console 出力結果

新人

以下のように短縮することも可能です。

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫',
    mem2 (arg) { // 短縮形
        return '新人';
    }
}

const value = akiba.mem2('鈴木'); 
console.log(value);

this

this は JavaScript の予約語の一つであり、変数名や関数名として使用することはできません。
メソッドの中で使われるケースが多いです。

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫',
    method() { // method という名前の method を定義
        console.log(this); // this は akiba オブジェクト「そのもの」を指す
        console.log(akiba); // 上記と同じ結果となる
        console.log(this === akiba); //比較演算子による結果は true となる
    }    
}

akiba.method();
Console 出力結果

{name: ‘運用 GP ‘, leader: ‘山田太郎’, mem1: ‘木村和夫’, method: ƒ}
{name: ‘運用 GP ‘, leader: ‘山田太郎’, mem1: ‘木村和夫’, method: ƒ}
true

this は akiba オブジェクトそのものを指しています。

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫',
    method() {
        console.log(this);        
    }    
}

const ueno = {
    name: '運用 GP2 ',
    leader: '荒川庄司',
    mem1: '田中一郎',
    method() {
        console.log(this);
    }
}

akiba.method();
ueno.method();
Console 出力結果

{name: ‘運用 GP ‘, leader: ‘山田太郎’, mem1: ‘木村和夫’, method: ƒ}
{name: ‘運用 GP2 ‘, leader: ‘荒川庄司’, mem1: ‘田中一郎’, method: ƒ}

this には method を持っているオブジェクトが紐づいています。

メソッドを使ってテンプレートリテラルを実行

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫',
    introduce() { // オブジェクトにメッソドを定義。引数なし
        console.log(`秋葉原グループ名は${this.name}です。リーダーは${this.leader},メンバーの一人は${this.mem1}です。`);
    }
}

akiba.introduce();
Console 出力結果

秋葉原グループ名は運用 GP です。リーダーは山田太郎,メンバーの一人は木村和夫です。

オブジェクトを value としたプロパティ

const unyo = { // unyo という定数を定義
    akiba: { // akiba というプロパティがあり、value がオブジェクトとなっている
        name: '運用 GP ',
        leader: '山田太郎',
        mem1: '木村和夫'
    },
    ueno: {
        name: '運用 GP2 ',
        leader: '荒川庄司',
        mem1: '田中一郎'
    },
    kanda:{
        name: '運用 GP3 ',
        leader: '加藤次郎',
        mem1: '鈴木花子'
    }
}

console.log(unyo.ueno.leader);
Console 出力結果

荒川庄司

オブジェクトの中に akiba、ueno、kanda という 3 つのプロパティがあり、さらにそれぞれオブジェクトを持っています。

配列 (Array) オブジェクト

複数のデータを順番に並べてひとまとめにするもので、オブジェクトの一つです。

配列の出力

const arr = ['富士山','北岳','奥穂高岳'] ; // 配列は角カッコでくくる。富士山、北岳のような値を「要素」と呼ぶ
console.log(arr[1]); // 「北岳」を参照。要素の番号を指定する

// テンプレートリテラルを使って出力
console.log(`日本で一番高い山は${arr[0]}です。`); // arr の中の番号はインデックスと呼ぶ
Console 出力結果

北岳
日本で一番高い山は富士山です。

配列の番号は富士山が arr[0]、北岳が arr[1]、奥穂高岳が arr[2] となります。

配列の要素の書き換え

配列はインデックスを指定し、要素を書き換えることが可能です。

const arr = ['富士山','北岳','奥穂高岳'] ;

console.log(arr); // ここまで配列 2 は奥穂高岳

arr[2] = '間ノ岳'; // 要素の書き換え

console.log(`日本で三番目に高い山は${arr[2]}です。`);

console.log(arr);
Console 出力結果

(3) [‘富士山’, ‘北岳’, ‘奥穂高岳’]
日本で三番目に高い山は間ノ岳です。
(3) [‘富士山’, ‘北岳’, ‘間ノ岳’]

「奥穂高岳」が「間ノ岳」に書き換えられました。

length

length プロパティは配列の要素数を表します。

let arr = ['富士山','北岳','奥穂高岳']; // 変数 arr に配列を定義

 for(let i = 0; i < arr.length; i++) { // arr.length は配列の要素数を取得する
    // 配列の要素数分{}内の処理を繰り返す
    console.log(arr[i]); // arr の i 番目を出力
    // i は今はループの何回目かといった意味
 }

//  1 回目 console.log(arr[0])
//  2 回目 console.log(arr[1])
//  3 回目 console.log(arr[2])
Console 出力結果

富士山
北岳
奥穂高岳

const arr = ['富士山','北岳','奥穂高岳'] ;
console.log(arr.length); // 要素の数を取得

const emptyArr = []; // 空配列を作成
console.log(emptyArr.length);

const yamaRank = [
    '富士山',
    '北岳',
    '奥穂高岳',
    '間ノ岳',
    '槍ヶ岳',
    '悪沢岳'
];
console.log(yamaRank.length); // 要素の数を取得

for (let i = 0; i < yamaRank.length; i++) {
    console.log(`日本で${i+1}番目に高い山は${yamaRank[i]}です。`);
}
Console 出力結果

3
0
6
日本で1番目に高い山は富士山です。
日本で2番目に高い山は北岳です。
日本で3番目に高い山は奥穂高岳です。
日本で4番目に高い山は間ノ岳です。
日本で5番目に高い山は槍ヶ岳です。
日本で6番目に高い山は悪沢岳です。

const yamaRank = [
    '富士山',
    '北岳',
    '奥穂高岳',
    '間ノ岳',
    '槍ヶ岳',
    '悪沢岳'
];

for(const yama of yamaRank) { // yamaRank の配列の先頭から 1 つずつ値を取り出し、yama の名前を付ける
    console.log(`${yama}は日本の山です。(for-of)`) // 結果は下と同じになる。インデックスを使わない場合はこちらが適している
}

for (let i = 0; i < yamaRank.length; i++) {
    const yama = yamaRank[i]; // 一旦 yama として要素を取り出す
    console.log(`${yama}は日本の山です。(for)`); // i が 0-5 まで 1 ずつ増えて、配列の先頭から文字列を取り出す
}
Console 出力結果

富士山は日本の山です。(for-of)
北岳は日本の山です。(for-of)
奥穂高岳は日本の山です。(for-of)
間ノ岳は日本の山です。(for-of)
槍ヶ岳は日本の山です。(for-of)
悪沢岳は日本の山です。(for-of)
富士山は日本の山です。(for)
北岳は日本の山です。(for)
奥穂高岳は日本の山です。(for)
間ノ岳は日本の山です。(for)
槍ヶ岳は日本の山です。(for)
悪沢岳は日本の山です。(for)

インデックスを使用しない場合、for-of 構文が適しています。

配列のメソッド

push

配列へ要素を追加します。

const yamaRank = [
    '富士山',
    '北岳',
    '奥穂高岳',
    '間ノ岳',
    '槍ヶ岳',
    '悪沢岳'
];

console.log(yamaRank);

yamaRank.push('赤石岳'); // 配列の末尾に追加

console.log(yamaRank);
Console 出力結果

(6) [‘富士山’, ‘北岳’, ‘奥穂高岳’, ‘間ノ岳’, ‘槍ヶ岳’, ‘悪沢岳’]
(7) [‘富士山’, ‘北岳’, ‘奥穂高岳’, ‘間ノ岳’, ‘槍ヶ岳’, ‘悪沢岳’, ‘赤石岳’]

配列の末尾に「赤石岳」が追加されました。

slice

配列の一部を切り取ります。

const yamaRank = [
    '富士山',
    '北岳',
    '奥穂高岳',
    '間ノ岳',
    '槍ヶ岳',
    '悪沢岳'
];

console.log(yamaRank);

const yamaRank2 = yamaRank.slice(2,5); // slice メソッドは 引数を 2 つとる

console.log(yamaRank2);
Console 出力結果

(6) [‘富士山’, ‘北岳’, ‘奥穂高岳’, ‘間ノ岳’, ‘槍ヶ岳’, ‘悪沢岳’]
(3) [‘奥穂高岳’, ‘間ノ岳’, ‘槍ヶ岳’]

配列の 2 番目から 4 番目までを切り取って出力します。5 番目は含みません。
slice(2) とすると (引数をひとつ省略すると) 2 番目から最後の配列まで出力されます。
slice() とすると (引数をすべて省略すると) 全ての配列が出力されます。

concat

配列を結合させます。

const kita = ['奥穂高岳','槍ヶ岳','白馬岳','剣岳','燕岳'];
const minami = ['北岳','間ノ岳','農鳥岳'];

const alps = kita.concat(minami); // kita と minami をくっつける 

console.log(alps);

console.log(kita); // 元の配列に影響はない

console.log(minami); // 元の配列に影響はない
Console 出力結果

(8) [‘奥穂高岳’, ‘槍ヶ岳’, ‘白馬岳’, ‘剣岳’, ‘燕岳’, ‘北岳’, ‘間ノ岳’, ‘農鳥岳’]
(5) [‘奥穂高岳’, ‘槍ヶ岳’, ‘白馬岳’, ‘剣岳’, ‘燕岳’]
(3) [‘北岳’, ‘間ノ岳’, ‘農鳥岳’]

map

const arr = [1,2,3,4,5];

const f = (x) => { // 引数 x の関数 f
    return 10 * x; // 返値を map メソッドにわたす
    };
    // 関数に渡す関数なのでコールバック関数と呼ばれる

const mapped = arr.map(f); // map メソッド。関数 f を引数としている
// map メソッドは関数を受け取る関数なので「高階関数」と呼ばれる
// arr の配列オブジェクトの要素に対して f の関数を適用させたものを配列オブジェクトとして返値とする

// [f(arr[0]),f(arr[1]),f(arr[2]),f(arr[3]),f(arr[4])]
// x が 1 の時は f は 10 * 1
// x が 2 の時は f は 10 * 2 

console.log(mapped); 
Console 出力結果

(5) [10, 20, 30, 40, 50]

メソッドや関数を知るうえで重要なことは引数と返値の理解です。
どんなものを受け取るのか、どんなものを返すのかを常に意識することが重要です。map メソッドの場合、返値はアレイオブジェクトになります。
ちなみに map メソッドは非破壊的メソッドです。(後述)

const arr = [1,2,3,4,5];

const f = (x) => { 
    return `x = ${x}`; // テンプレートリテラルで文字列変換
    };

const mapped = arr.map(f);

console.log(mapped);
Console 出力結果

(5) [‘x = 1’, ‘x = 2’, ‘x = 3’, ‘x = 4’, ‘x = 5’]

上記の省略形です。

const arr = [1,2,3,4,5];

const mapped = arr.map((x) => {
    return `x = ${x}`;
});

console.log(mapped);

更に省略形です。

const arr = [1,2,3,4,5];

const mapped = arr.map(x => `x = ${x}`); 

console.log(mapped);

filter

配列から特定要素を取り除きます。

const arr = [1,2,3,4,5];

const f = (x) => {
    return x % 2 === 0; // 引数が一つで返り値は boolean 型のコールバック関数
    // 引数 x が 2 で割り切れたら true そうでなければ false を返す関数
};

const filtered = arr.filter(f);
// f の関数から渡された結果が true なら残す、false なら取り除く

console.log(filtered);
Console 出力結果

(2) [2, 4]

偶数だけフィルターされました。
filter メソッドは非破壊的メソッドです。(後述)

上記の省略形です。

const arr = [1,2,3,4,5];

const filtered = arr.filter(x => x % 2 == 0);

console.log(filtered);

reduce

const arr = [1,2,3,4,5,6];

const f = (x,y) => { // 2つの引数を取る関数 f
    return x * y; // 返す値は一つ
};

const reduced = arr.reduce(f); // コールバック関数 f を受け取る

console.log(reduced);
Console 出力結果

720

以下のようなイメージとなります。

f(f(f(arr[0],arr[1]),arr[2]),arr[3])
青色内・・・1 * 2 = 2 arr[0] と arr[1] を掛け合わせると 2 になる
赤色内・・・2 * 3 = 6 2 と arr[2] を掛け合わせると 6 になる
緑色内・・・6 * 4 = 24 6 と arr[3] を掛け合わせると 24 になる
上記を arr[5] まで繰り返すと 720 の結果が得られます。
このような計算は「畳み込み」と呼ばれています。

多次元配列

配列を要素に持つ配列です。

出力とアクセス

const A = [
    ['白',`黒`,'黒'], // 0 番目の配列
    ['黒',`白`,'黒'], // 1 番目の配列
    ['黒',`黒`,'白'], // 2 番目の配列
    ['白',`白`,'白']  // 3 番目の配列
];

console.table(A); // 表形式で出力

A[0][1] = '白'; // 1 列目の 2 番目に「白」を代入

console.table(A);
Console 出力結果
(index)012
0‘白’‘黒’‘黒’
1‘黒’‘白’‘黒’
2‘黒’‘黒’‘白’
3‘白’‘白’‘白’
(index)012
0‘白’‘白’‘黒’
1‘黒’‘白’‘黒’
2‘黒’‘黒’‘白’
3‘白’‘白’‘白’

九九表の作成

const kuku = []; // 空の配列を定義

for(let i = 0; i < 9; i++) {
    kuku.push([]); // 空の kuku 配列にさらに空の配列を入れる
    for(let j= 0; j < 9; j++) {
        kuku[i].push((i+1)*(j+1)); // kuku の i 番目に push(追加) する
    }
}

console.table(kuku);
Console 出力結果
(index)012345678
0123456789
124681012141618
2369121518212427
34812162024283236
451015202530354045
561218243036424854
671421283542495663
781624324048566472
891827364554637281

特定の要素が含まれているか判定

const array = [5,7,2,4];

const value = 7;

const L = array.length; // array の length をとる

let included = false; // included という変数を定義し、false を代入

for(let i = 0; i < L; i++) {
    if(array[i] === value) {
        included = true; // 7 が含まれていれば included を true にして終了
        break;
    }
}

if(included) {
    console.log('yes'); // included が true になっていれば yes
}
else{
    console.log('no'); // inculudedが false のままであれば 7 はない
}
Console 出力結果

yes

配列に 7 が含まれており、included は true に変更され、break で終了し、console.log に yes が出力されています。

素数を求める

20 以下の素数を小さい順にコンソールに出力します。
素数とは 2 以上の整数で、1 と自身以外で割り切れない整数です。

const MAX_NUM = 20;

const END = MAX_NUM + 1; // 最大 20 まで。20 を含めるため +1

for (let i = 2; i < END; i++) { // 2 から 20 まで for 文をまわす
    for(let j = 2; j <= i ; j++) { // j を 2 から 1 ずつ増やす。j は 2 から i まで for 文を回す
        if(j === i) { // j と i が等しければ (一度も break に到達しなければ) i は素数
            console.log(i);
        }
        if(i % j === 0) { // i が j で割り切れたら break
            break;
        }
    }
}
Console 出力結果

2
3
5
7
11
13
17
19

例えば、i = 4 で j =2 の場合、4 は 2 で割り切れるので、breakし、処理は中断されます。
よって 4 は素数ではありません。

ミュータブルとイミュータブル

値の性質のことで、ミュータブルは値が変化し、イミュータブルは値が変化しません。

ミュータブルの例

オブジェクトや配列はプロパティや要素を書き換えられるのでミュータブルです。

オブジェクト

const akiba = {
    name: '運用 GP ',
    leader: '山田太郎',
    mem1: '木村和夫'     
}

console.log(akiba);

akiba.name = '運用グループ'; // プロパティの書き換え

console.log(akiba);
Console 出力結果

{name: ‘運用 GP ‘, leader: ‘山田太郎’, mem1: ‘木村和夫’}
{name: ‘運用グループ’, leader: ‘山田太郎’, mem1: ‘木村和夫’}

「運用 GP」 → 「運用グループ」に書き換えられています。

配列

const arr = ['富士山','北岳','奥穂高岳'] ;
arr[2] = '間ノ岳'; // 要素の書き換え

console.log(`日本で三番目に高い山は${arr[2]}です。`);
console.log(arr);
Console 出力結果

日本で三番目に高い山は間ノ岳です。
(3) [‘富士山’, ‘北岳’, ‘間ノ岳’]

「奥穂高岳」 → 「間ノ岳」に書き換えられています。

イミュータブルの例

プリミティブ型の値はイミュータブルな値となります。

const str = '文字列型';
const num = 100;

「文字列型」、「100」などの値は絶対に変化しない値となります。

const と let

const は再代入不可能な名前です。
let は再代入可能な名前です。

const 定数は再代入できない

const akiba = {
    name:'山田太郎',
    age: 35 
}

console.log(akiba);

akiba = { // 再代入
    name:'木村和夫',
    age: 18
}

console.log(akiba);
Console 出力結果

{name: ‘山田太郎’, age: 35}
main.js:11 Uncaught TypeError: Assignment to constant variable.

定数「akiba」を再代入するとエラーになります。

let 変数は再代入可能

let akiba = {
    name:'山田太郎',
    age: 35 
}

console.log(akiba);

akiba = { // 再代入
    name:'木村和夫',
    age: 18
}

console.log(akiba);
Console 出力結果

{name: ‘山田太郎’, age: 35}
{name: ‘木村和夫’, age: 18}

変数「akiba」を再代入することが可能です。

const 定数でも内容 (値) は修正可能

const akiba = {
    name:'山田太郎',
    age: 35 
}

console.log(akiba);

akiba.age++; // age プロパティを 1 増やす

console.log(akiba);
Console 出力結果

{name: ‘山田太郎’, age: 35}
{name: ‘山田太郎’, age: 36}

オブジェクトの内容が更新されています。

const akiba = {
    name:'山田太郎',
    age: 35 
}

console.log(akiba);

akiba.name = '木村和夫';

akiba.age = 18;

console.log(akiba);
Console 出力結果

{name: ‘山田太郎’, age: 35}
{name: ‘木村和夫’, age: 18}

const 定数が再代入されたわけではなく、「山田太郎」が「木村和夫」に改名したイメージです。
オブジェクト自体はミュータブルなので、変化してしまうということです。

破壊的メソッドと非破壊的メソッド

破壊的メソッド

const arr = [1,2,3];
console.log(arr); 

const reversed = arr.reverse(); // 配列の順番を逆にする reverse メソッド

console.log(reversed);
console.log(arr); // arr オブジェクト自身がこの段階でも反転している
Console 出力結果

(3) [1, 2, 3]
(3) [3, 2, 1]
(3) [3, 2, 1]

reverse メソッドのようにオブジェクト自身のプロパティを書き換えてしまうメソッドを「破壊的メソッド」と呼びます。

const arr = [1,2,3];
console.log(arr); 

const reversed = arr.slice().reverse(); // コピーした配列に対して reverse メソッドを実行

console.log(reversed);
console.log(arr); // arr オブジェクトは影響を受けていない
Console 出力結果

(3) [1, 2, 3]
(3) [3, 2, 1]
(3) [1, 2, 3]

slice メソッドで一旦コピーした配列に対して reverse メソッドを実行すると、元のオブジェクトが書き換えられることを回避できます。

引数を受け取り、値を返す以外に関数が何か処理を行った場合、それを副作用と呼ぶびます。
破壊的メソッドは自身のオブジェクトのプロパティを書き換えるという、副作用をもったメソッドと言えます。

非破壊的メソッド

副作用がなく、値を受け取り、計算して値を返すだけのメソッドを「非破壊的メソッド」と呼びます。


コメント

タイトルとURLをコピーしました