JavaScriptのFunction()を学ぶ

以下のページでJavaScriptを体系的に学んでいます。 www.mojage.club

本記事は、JavaScriptのFunction()について纏めています。

Sponsored Link

Function()

ファンクションは値を返すreturnがあるか、もしくはシンプルに処理を走らせる為に使われます。 以下に基本的な足し算のファンクションオブジェクトを生成しました。addNumbersA()newオペレータを使い、addNumbersB()はよく見かけるなじみ深い記法です。

    var addNumbersA = new Function('num1', 'num2', 'return num1 + num2);
    console.log(addNumbersA(2, 2)); // 4
    
    var addNumbersB = function(num1, num2){return num1 + num2;};
    console.log(addNumbersB(2, 2)); // 4

function()コンストラクタは不特定数のパラメータとして渡せます。ただ最後のパラメータだけは、文字列を含むそのファンクション自体を表すステートメントになります。 つまり、function()はいくつかのパラメータを受け取り、最後のパラメータでreturnの様な返り値又は処理が記されている必要があります。

プロパティ/メソッド

Function()オブジェクトは、以下のプロパティを持っています。

種別 プロパティ/メソッド名
プロパティ prototype function.prototype

Function()オブジェクトのインスタンスは以下のプロパティ/メソッドを持っています。

種別 プロパティ/メソッド名
プロパティ constructor var myFunction = function(x, y, z){}; myFunction.constructor;
プロパティ length var myFunction = function(x, y, z){}; myFunction.length;
プロパティ name var myFunction = function(x, y, z){}; myFunction.name;
メソッド apply() var myFunction = function(x, y, z){}; myFunction.apply();
メソッド bind() var myFunction = function(x, y, z){}; myFunction.bind();
メソッド call() var myFunction = function(x, y, z){}; myFunction.call();
メソッド toString() var myFunction = function(x, y, z){}; myFunction.toString();

ファンクションの返り値

一般的にはファンクションは値を返す様に記述します。

    var sayHi = function() {
     return 'Hi';
    };
    
    console.log(sayHi()); // Hi

もし返り値を定義していない場合は、undefinedをを返します。

    var yelp = function() {
      console.log('I am yelping!');
    };
    
    console.log(yelp() === undefined); // true

JavaScriptのファンクションはファーストクラス

JavaScriptのファンクションはオブジェクトです。つまり、変数、array、objectを格納できます。そしてファンクションはオブジェクトや値を送り出すこともできるし、他のファンクションから受け取ることも出来ます。また、プロパティを持っています。これらのことから、JavaScriptにおいてファンクションはファーストクラスだと言うことが出来ます。 ファンクションを変数、array、オブジェクトとして格納する場合は以下の様になります。

    var funcA = function(){};            // calling like : funcA();
    var funcB = [function(){}];          // calling like : funcB[0]();
    var funcC = {method: function(){}};  // calling like : funcC.method(); or funcC['method']();

以下は、ファンクションを送ったり、返り値としてファンクションを指定したりしています。

    var fancD = function(func){
      return func        // this function send back a function that recieved.
    };
    
    var runFuncPassedToFuncD = funcD(function(){console.log('Hi');});  //the function is sent to the another function.
    
    runFuncPassedToFuncD(); // Hi

ファンクションはオブジェクトなので、プロパティを持つことができます。

    var funcE = function(){};
    funcE.answer = 'yup';
    console.log(funcE.answer);  // yup

パラメータ

パラメータはファンクションのスコープ内に値を渡す役割があります。

    var addFunction = function(number1, number2){
      var sum = number1 + number2;
      return sum;
    };
    
    console.log(addFunction(3, 3));  //6

thisarguments

thisargumentsは全てのファンクションで使用できます。 argumentsはファンクションに渡したパラメータが格納されているarrayオブジェクトです。

    var add = function(){
      return arguments[0] + arguments[1];
    };
    
    console.log(add(4, 4)); // 8

thisはそのペアレントオブジェクトを参照するために使用できます。ファンクションがグローバルスコープにて定義されている場合は、thisはグローバルオブジェクトになります。

    var myObject1 = {
      name: 'myObject1',
      myMethod: function(){console.log(this);}
    };
    myObject1.myMethod();  // myObject1
    
    var myObject2 = function(){console.log(this);};
    myObject2(); // window

arguments.callee

argumentsオブジェクトはcalleeというプロパティをもっています。これは、呼び出し元のファンクションを参照するものです。

    var foo = function foo() {
      console.log(arguments.callee);  // foo()
    }();

length

ファンクションオブジェクトの持つlengthプロパティとargumentsオブジェクトの持つlengthプロパティは似て非なる動きをします。 arguments.lengthは引き受けたパラメータの数を求めます。

    var myFunciton = function(z, s, d){
      return arguments.length;
    };
    console.log(myFunction());  // 0

ファンクションオブジェクトのlengthプロパティは、そのファンクションが期待しているパラメータの数を求めます。

    var myFunction = function(z, s, d, e, r, m, q){
      return myFunction.length;
    };
    console.log(myFunction());  // 7

パラメータの再定義

ファンクションのパラメータは再定義することができます。

    var foo = false;
    var bar = false;
    
    var myFunction = function(foo, bar){
      arguments[0] = true;
      bar = true;
      console.log(arguments[0], bar); // true true
    }
    myFunction();

ファンクションの途中停止

returnを使用することでファンクションが終わる前にキャンセルすることができます。

    var add = function(x, y){
      if(typeof x !== 'number' || typeof y !== 'number'){return 'pass in numbers';}
      return x + y;
    }
    console.log(add(3, 3)); // 6
    console.log(add('2', '2')); // pass in numbers

call()apply()

call()apply()は定義済みのファンクションを借りてきて実行することができます。 call()は一つ目のパラメータをthisに相当するオブジェクトを指定し、以降のパラメータを,で区切って渡します。 apply()は一つ目のパラメータをthisに相当するオブジェクトを指定し、以降のパラメータを配列で渡します。

    var greet = {
      runGreet: function(){
        console.log(this.name, arguments[0], arguments[1]);
      }
    }
    var cody = {name: 'cody'};
    var lisa = {name: 'lisa'};
    
    greet.runGreet.call(cody, 'foo', 'bar');     // cody foo bar
    
    greet.runGreet.apply(lisa, ['foo', 'bar']);  // lisa foo bar

即時実行するファンクションの例

    var sayWord = function() {console.log('Word 2 yo mo!);}();  //Word 2 yo mo!
    
    (function(msg){
      console.log(msg);
    })('Hi!');

ホイスティング

ファンクションはそれ自身が定義される前に実行出来てしまいます。これは、ファンクションの実行中に中断され、巻き上げ処理が発生し、実行可能となります。

    var speak = function(){
      sayYo();
      function sayYo() {console.log('Yo');}
    }();  // Yo
    
    console.log(sum(2, 2));
    function sum(x, y) {return x + y;}  //4

この動きの為に、予期せぬ挙動を招くことがあります。プロパティやメソッドの定義は先に行っておくようにするなど、コーディングルールで対処するようにしましょう。

再帰処理

ファンクションは自分自身を実行することが可能なので、以下の様に条件が達成されるまで繰り返す処理が可能です。

    var countDownFrom = function countDownFrom(num) {
      console.log(num);
      num--;
      if (num < 0){return false;}
      countDownFrom(num);
    };
    
    countDownFrom(5);  // 5, 4, 3, 2, 1, 0