頭脳一式

人の記憶なんて曖昧なもの。すべての情報を頭に記憶するなんてナンセンス。困ったらここに来ればいいじゃん?というスタンスで最強のナレッジベースを目指すブログ

【Javascript】jsにおける関数と引数の扱い

関数

Javascriptの関数は第一級オブジェクト(ファーストクラスオブジェクト)と云い
変数や配列に代入することが出来る。パラメータとして使うことも可能。

関数の定義、実行

// 関数の定義
function add(a,b){
    console.log(a + b);  // 15
}

// 関数の実行
add(10,5);

変数へ代入、呼び出し実行する方法

変数へ代入するときは、関数名を付けない。(無名関数)

// 変数へ代入する方法  
var subtract = function (a,b){
    console.log(a - b);  // 5
}

// 呼び出し実行
subtract(10,5);

パラメータとして使う方法

function add(a,b){
    console.log("add");
}

var add = function (a,b) {
    console.log(a + b);  // 15
}

function func(add) {
    add(); //add関数を呼び出しているわけではなく、引数に渡された関数を実行している。
}

func(add(5,10));  //func関数の引数としてadd関数を渡す。

変数へ代入した関数の定義情報を表示する方法

var add = function (a,b) {
    alert(a + b);
}

console.log(add); //カッコ演算子を付けずに呼び出すと関数の中身を見ることが出来る。

引数

Javaなどでは関数の定義どおりに引数を渡さないとエラーになるが、
Javascriptではエラーにならない。引数を多く渡しても少なく渡しても問題なく実行することができる。

引数を多く渡した場合の挙動

function view(a,b,c){
    console.log(a, b ,c); // 10 20 30
}

view(10,20,30,40,50);

引数を少なく渡した場合の挙動

function view(a,b,c){
    console.log(a, b ,c);  // 10 20 undefined
}

view(10,20);

引数を渡さなかった場合の挙動

function view(a,b,c){
    console.log(a, b ,c); // undefined undefined undefined
}

view();

上の実行結果をみると値が渡されなかった引数を参照すると「undefined」が返却されることがわかる。
そして多く渡した引数はargumentsオブジェクトを用いることで値を参照することができる。
argumentsオブジェクトは、関数のスコープ内で使用することができ、関数に渡されたすべての引数を管理している。

function view(a,b,c){
    console.log(arguments.length); // 5
    console.log(arguments[0], arguments[1], arguments[2]); // 10 20 30
}

view(10,20,30,40,50);

コールバッグとは

引数として渡される関数のことをコールバック関数と呼ぶ。
引数として渡すことで任意のタイミングで処理を実行することが可能になる。
非同期処理の場合に、処理が終わってから関数を実行したい場合に有効。

function func1(callback){
    console.log("test1");
    callback();  //このコードが実行されたとき、引数に渡された関数が実行されることになる。
}


func1( function() {
    console.log("test2");  //test1 test2の順で出力される。
});

変数の巻き上げ

Javascriptでは関数内のいかなる場所でもvarを用いることで変数の宣言ができる。
但し、この変数はどこで宣言されたとしても関数の先頭で宣言されたときと同様の振る舞いをする。

var str = "abc";

var func = function(){
    console.log(str);  //undefined
    
    var str = "def";
    console.log(str);  //def
}

func();

上のコードは下記と同義。
宣言部分のみが先頭で行われたと見做される。(初期化まではされていないことに注意)

var str = "abc";

var func = function(){
    var str;
    console.log(str);  //undefined
    
    str = "def";
    console.log(str);  //def
}

func();

巻き上げされたままグローバル変数を呼び出したいときは「this.変数名」の形にする。

var str = "abc";

var func = function(){
    console.log(this.str);  //abc
    
    var str = "def";
    console.log(str);       //def
}

func();

関数内で使用するすべてのローカル変数を関数の先頭で宣言することにより巻き上げを防げる。

即時関数

関数を定義すると同時に実行することができる関数のことを即時関数と呼ぶ。
この即時関数は主に一回だけ必要な処理がある場合に使用する。
無名関数で即時関数を作ることでグローバルスコープの汚染(不要なメンバの追加)を回避することができる。
下のコードのように無名関数全体を()で括ることで定義・実行することができる。

//引数なしver
(function(){
    console.log("即時関数1");    // 即時関数1
}());

//引数ありver
(function(a,b){
    console.log(a + b);     // 即時関数2
}("即時","関数2"));