1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptのfunction命令は静的な構造を宣言することを確かめてみた

1
Posted at

はじめに

JavaScriptのfunction命令は、コードを解析/コンパイルするタイミングで、関数を登録しているらしい。
つまり、function命令は、実行時にはすでにコード内の構造の一部となっているので、同じかそれ以下のスクリプトブロック(<script>)内であれば、関数を宣言する行より前でも関数を呼び出すことができる。

三角形の面積を求める関数を作成

まずは、普通に三角形を求める関数を作成する。

main.html
<!--jsを読み込むためのhtml-->
<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script src=./triangle.js></script> <!--読み込むjs-->
    </body>
</html>

triangle.js
        function getTriangle(base, height){
            return base*height/2;
        }

        console.log(getTriangle(5, 2));  //5

function命令より前で関数を呼び出してみる

triangle.js
        console.log(getTriangle(5, 2));  //5←呼び出せる。

        function getTriangle(base, height){
            return base*height/2;
        }

異なるスクリプトブロックから呼び出してみる。

main.html
<!--jsを読み込むためのhtml-->
<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script src="./test.js"></script><!--新しく読み込むjs-->
        <script src=./triangle.js></script>
    </body>
</html>

triangle.js
       // console.log(getTriangle(5, 2));  コメントアウトします 

        function getTriangle(base, height){
            return base*height/2;
        }

test.js
        console.log(getTriangle(5, 2)); //ここから呼び出します。

結果

test.js:1 Uncaught ReferenceError: getTriangle is not defined
    at test.js:1

呼び出せなかった。なぜならブラウザは<script>要素の単位で、順にスクリプトを処理していくためである。※同じスクリプトかtriangle.jsより下の行であれば呼び出せる。

function命令ではなく、関数リテラルやfunctionコンストラクタの場合はどうか

関数リテラル

Sankaku.js
    console.log("getSankaku:"+getSankaku(5, 2));

    var getSankaku = function(base, height){
        return base*height/2;
    };

//Uncaught TypeError: getSankaku is not a function

frunctionコンストラクタ

getDreieck.js
console.log("getDreieck:"+getDreieck(5, 2));

getDreieck = new Function('base', 'height', 'return base*height/2');

//Uncaught TypeError: getDreieck is not a function

両方ともエラーになる。理由はfunction命令とは異なり、関数リテラルとFunctionコンストラクタは共に実行時に評価されるからである。

まとめ

function命令は静的な構造を宣言するため(解析の時点で関数を登録している)、同じかそれ以下のスクリプトブロック内であれば、どこからでも呼び出せる。

関数リテラル及びFunctionコンストラクタは動的に呼び出されるため、(実行時に評価される)必ず関数を宣言した後でなければ呼び出すことが出来ない。

参考

JavaScript本格入門

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?