今回は、プログラミングの醍醐味である 関数 について学習していきます。また、ここではJavaScriptのオブジェクトについても学習します。

音楽にあわせて踊る動物たち

オブジェクトとは

オブジェクトを一言で表すと「」です。

現実世界の「人」も「パソコン」も「本」も「商品」もオブジェクトということになります。

「人」には多くの情報があります。「名前」や「生年月日」「性別」「血液型」などです。

プログラミングの世界では、これらの情報を一つに集たデータのことをオブジェクトといいます。

オブジェクトは関連する変数や関数を集めたもの

オブジェクトとは、値である文字列や数値、真偽値に加えて、配列や関数など、関連するデータを集合させたものです。

配列と異なるのは、配列はリスト形式でインデックス番号を用いてデータにアクセスしましたが、オブジェクトは メンバー と呼ばれるデータの名前を使用してデータにアクセスします。

オブジェクトの操作


// myDog というオブジェクトを作成します
let myDog = {};
console.log(myDog);

// myDog にメンバーを追加し値を設定します
myDog.type = 'dog';
myDog.name = 'ポチ';
myDog.age = 2;
myDog.gender = 'メス';
myDog.feeds = ['ユニ・チャーム愛犬元気', 'ドギーマン チーズキューブ', 'おいしい犬ごはん'];
console.log(myDog);
// {
//     age: 2
//     feeds: Array(3)
//         0: "ユニ・チャーム愛犬元気"
//         1: "ドギーマン チーズキューブ"
//         2: "おいしい犬ごはん"
//         length: 3
//     gender: "メス"
//     name: "ポチ"
//     type: "dog"
// }

// 名前をコンソールに出力します
console.log( myDog.name );   // ポチ

// 食べている餌の名前を全てコンソールに出力します
for( let i = 0; i < myDog.feeds.length; i++ ) {
    console.log(myDog.feeds[i]);
}
                

オブジェクトの作成時に、以下のようにオブジェクト内のデータをまとめて作成することもできます。


// 以下のように作成することもできます
let myCat = {
    age: 4,
    feeds: ['銀のスプーン', 'ジューシー'],
    gender: "メス",
    name: "ミイ",
    type: "cat"
}
                

メンバー名がケバブケースである場合のアクセス

JavaScriptではケバブケースの変数を定義することができません。しかし、以下のようにすることでケバブケースやその他のメンバー名でオブジェクトに値を設定することができます。


// もしメンバー名がケバブケースだった場合、ドットではアクセスすることができません
// obj.member-name = 'name';  ❌

// 角括弧を使用してアクセスすることができます
obj['member-name'] = 'name';
            

関数(function)について

Params into function and get return value(引数を関数に渡して返り値を得る)

関数とは、例えるならミキサー

プログラミング初学者にとって一つの障壁になるのが、この関数です。
数学の関数とは似ているようで異なります。

関数は、値を受け取って、決められた処理を実行し、結果を返すといったプログラムのことです。受け取る値もなく、返す結果もないが、特定の処理を実施する関数もあります。

この関数は、自由に作成することができ、一度作れば何度でも呼び出して使うことができます。

簡単に言うと、ある処理をひとまとめにしたものです。

同じ処理が繰り返し行われる場合などに関数を定義しておくと、プログラミングの可読性の向上や、修正などのメンテナンスが容易になります。

無名関数と名前付き関数

関数は自由に定義できますが、「関数そのものに名前を付ける」場合と、「関数を変数に代入する」場合があります。

関数名または変数名を使用して「関数を呼び出す」ことで使用します。

無名関数

変数に代入したり関数の引数に渡して使用します。

function(引数) {
    実行される処理を記述し、
    return; で処理を終了します
    返却する必要のある値があれば return 戻り値; とすることで返すことができます
}
                

名前付き関数

関数名を使用して呼び出すことができます。

function 関数名(引数) {
    実行される処理を記述し、
    return; で処理を終了します
    返却する必要のある値があれば return 戻り値; とすることで返すことができます
}

関数は、 関数名( [引数]... ); とすることで呼び出すことができます
                

functionの作成と実行

無名関数と名前付き関数を作成して実行してみましょう。


// 変数weather を定義し 晴れ で初期化します
let weather = '晴れ';

// 無名関数を作成して 変数makeWeatherSentense に代入します
const makeWeatherSentense = function( weather ) {
    if(!weather) {
        weather = '不明';
    }
    return '今日の天気は、' + weather + 'です';
}
// 関数を呼び出し、戻り値を 変数sentense に代入します
let sentense = makeWeatherSentense( weather );
// 変数sentense をコンソールに出力します
console.log(sentense);


// 名前付き関数viewWeatherSentense を作成します
function viewWeatherSentense ( weather ) {
    if(!weather) {
        weather = '不明';
    }
    console.log('今日の天気は、' + weather + 'です');
    // 戻り値がない場合で、この後に続く処理がない場合は return; を省略できます
}
// 関数を呼び出します
viewWeatherSentense( werather );
                

関数から関数を呼び出す

関数内から関数を呼び出すこともできます。

上記の関数 viewWeatherSentense の処理は、変数 makeWeatherSentense とほとんど同じであるため関数を呼び出して簡略化します。


function viewWeatherSentense ( weather ) {
    // 名前付き関数 makeWeatherSentense の引数に この関数で受け取った 引数weather を渡し実行します
    // 戻り値をコンソールに出力します
    console.log( makeWeatherSentense( weather ) );
}
                

グローバル変数とローカル変数

Global and Local(グローバルとローカル)

基本的に同じプログラム内で同じ名前の変数名を定義しようとするとエラーになります。 

複数の同一の変数名が存在すると、コンピュータがどの変数のことを指しているのか分からないので当然ですね。

しかし、変数の生存期間には違いがあり、グローバル変数とローカル変数に分かれます

グローバル変数

グローバル変数は、関数の外側で定義した変数で、関数内でも呼び出すことが可能です

プログラムが終了するまで生存し続けます。

ローカル変数

ローカル変数は、関数内で定義された変数のことで、関数が終了したタイミングで廃棄されます。 ローカル変数ではグローバル変数と同名の変数を定義できますが、使う際にはグローバル変数ではなくローカル変数の値となります。

グローバル変数とローカル変数の例


// グローバル変数hello を定義します
let hello = 'Hello!';

function greeting() {
    // 関数内で グローバル変数hello を呼び出してみます
    console.log(hello);
}
greeting(); // Hello!


function sayHello() {
    // 関数内で グローバル変数hello と同じ名前の変数を定義します
    let hello = 'Hello World!';
    console.log(hello);
}
sayHello(); // 'Hello World!'


function setGoodMorning() {
    // ローカル変数greet を定義します
    let greet = 'Good morning!';
}
// ローカル変数greet を グローバルで使用してみます
console.log(greet); // Uncaught ReferenceError: greet is not defined
            

スコープについて

スコープとは、グローバル変数やローカル変数など、変数を呼び出せる範囲のことをいいます。
スコープにも グローバルスコープ ローカルスコープ があります。

グローバルスコープ

どこからでも呼び出し可能な変数のことで、グローバル変数が持つ範囲になります。

ローカルスコープ

関数スコープブロックスコープに分かれており、グローバル変数以外の変数は、このどちらかに該当します。

関数スコープ

関数内で定義された変数が持つ範囲で、関数が終了するたびに破棄されます。

ブロックスコープ

if文 や for文 などの波括弧({})内で定義された変数が持つ範囲で、ブロックを抜けると破棄されます。

スコープの例


let scope = 'global';
const demo = function() {
    let scope = 'function';
    if( true ) {
        let scope = 'block';
        console.log( scope ); // block
    }
    console.log( scope ); // function
}
demo();
console.log( scope ); // global
            

スコープを利用した関数の使い方の例


// 例: 変数 count をインクリメントする関数を作成する

// -----------
// スコープを利用しない場合
// -----------
// この count はグローバル変数です
let count = 0;
function incrimentCount() {
    return count++;
}
console.log(incrimentCount()); // 0
console.log(incrimentCount()); // 1
console.log(incrimentCount()); // 2
// count を初期化します
count = 0;
console.log(incrimentCount()); // 0


// -----------
// スコープをうまく利用した場合
// -----------
function closure() {
    // この count はこの関数が実行された場合に実行されます
    let count = 0;
    // 無名関数を 戻り値 として返します
    return function() {
        // 無名関数内で count をインクリメントします
        return count++;
    }
}

// 新しく closure を実行し、戻り値である 無名関数を closureDemo に代入します
let closureDemo = closure();
console.log(closureDemo()); // 0
console.log(closureDemo()); // 1
console.log(closureDemo()); // 2
// 新しく closure を実行したので count が初期化されています
closureDemo = closure();
console.log(closureDemo()); // 0
            

課題

オブジェクト person の名前(name)を 姓 名 の順でコンソールに表示するプログラムを作成してください


let person = {
    name: {
        first: 'のび太',
        last: '野比'
    },
    gender: 'male',
    country: 'JP'
}
// ここからコーディングしてください
                
課題1の オブジェクト person に新しく メンバー hobby を作成し値として ‘寝ること’ を設定して、メンバー hobby をコンソールに表示するプログラムを作成してください

0から23までのランダム値である 整数 hour を使用して、hour
0から11までのときは「午前xx時です」
12ピッタリのときは「正午です」
13から23までのときは「午後xx時です」
とコンソールに表示する 関数viewHour を作成して実行してください


// 0 - 23までの整数が返却されるプログラム
let hour = Math.floor(Math.random() * Math.floor(24))
// ここからコーディングしてください
                

任意の名前の引数で値を受け取り、

引数が数値なら 50を足し、

文字列であれば 任意の文字列を末尾に足した値を 戻り値として返却する

関数test2 を作成してください。
足す文字列は自由でOKです。

以下のコードで実行(確認)してみて、値が同じであればクリアです。


// 確認コード
console.log(test2('文字列'));    // 文字列[任意の文字列]
console.log(test2('22'));       // 22[任意の文字列]
console.log(test2(42));         // 92
console.log(test2([]));         // undefined
console.log(test2(true));       // undefined
console.log(test2({}));         // undefined