JavaScriptは一歩ずつ学ぶ(Function類と関数の本質)

2974 ワード

Functionオブジェクト(クラス)
ECMAScriptが最も興味のあるのは、関数が機能的に完全なオブジェクトであることに過ぎないかもしれません.
Functionクラスは、開発者が定義した任意の関数を表すことができます.
関数をFunctionクラスで直接作成する文法は以下の通りです.
var function_name = new function(arg1, arg2, ..., argN, function_body)
上記の形態では、各argは一つのパラメータであり、最後のパラメータは関数本体(実行するコード)である.これらのパラメータは文字列でなければなりません.
この関数を覚えていますか?
function sayHi(sName, sMessage) {

  alert("Hello " + sName + sMessage);

}

このように定義することもできます.
var sayHi 

= 

new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

文字列の関係のために、このような形で書くのは難しいですが、関数が引用型にすぎないことを理解するのに役立ちます.それらの行為はFunctionクラスで明確に作成された関数挙動と同じです.
この例を見てください.
function doAdd(iNum) {

  alert(iNum + 20);

}



function doAdd(iNum) {

  alert(iNum + 10);

}



doAdd(10);	//   "20"

ご存知のように、第二の関数は第一の関数を積載し、doAdd(10)は「20」ではなく「30」を出力しました.
このコードブロックを下の形で書き直すと、この概念が分かります.
var doAdd = new Function("iNum", "alert(iNum + 20)");

var doAdd = new Function("iNum", "alert(iNum + 10)");

doAdd(10);

このコードを確認してください.doAddの値は異なるオブジェクトを指すポインタに変更されました.関数名は、関数オブジェクトの参照値だけを指します.他のオブジェクトと同じ挙動です.二つの変数を同じ関数に向けることもできます.
var doAdd = new Function("iNum", "alert(iNum + 10)");

var alsodoAdd = doAdd;

doAdd(10);	//   "20"

alsodoAdd(10);	//   "20"

ここで変数doAddは関数として定義され、次にalsodoAddは同じ関数を指すポインタとして宣言される.これらの2つの変数を使って、関数のコードを実行し、同じ結果「20」を出力します.したがって、関数名が関数の変数だけを指す場合、関数をパラメータとして他の関数に渡すことができますか?答えは肯定です.
function callAnotherFunc(fnFunction, vArgument) {

  fnFunction(vArgument);

}



var doAdd = new Function("iNum", "alert(iNum + 10)");



callAnotherFunc(doAdd, 10);	//   "20"

上記の例では、calAnotherFun()は2つのパラメータ-呼び出す関数と、その関数に渡すパラメータがあります.このコードは、doAdd()をカルルAnotherFnc()関数に渡します.パラメータは10で、出力は20です.
注意:関数はFunctionコンストラクタを使って関数を作成することができますが、関数を定義するのは伝統的な方法よりもはるかに遅いからです.ただし、すべての関数は、Functionクラスの例とみなされるべきである.
Functionオブジェクトのlength属性
前に述べたように、関数は参照タイプに属するので、属性と方法もあります.
ECMAScriptで定義された属性lengthは、関数が期待するパラメータの個数を宣言しています.たとえば:
function doAdd(iNum) {

  alert(iNum + 10);

}



function sayHi() {

  alert("Hi");

}



alert(doAdd.length);	//   "1"

alert(sayHi.length);	//   "0"

関数doAdd()はパラメータを定義していますので、lengthは1です.sayHi()はパラメータが定義されていませんので、lengthは0です.
覚えてください.いくつかのパラメータを定義しても、ECMAScriptは任意の複数のパラメータ(最大25個)を受け入れることができます.この点は「関数概要」という章で説明しました.属性lengthは、デフォルトの場合に予想されるパラメータの個数を見るためだけの簡便な方法を提供します.
Functionオブジェクトの方法
Functionオブジェクトは、すべてのオブジェクトと共有するvalueOf()方法とtostring()方法もあります.この二つの方法はいずれも関数のソースコードであり、デバッグ時に特に有用である.たとえば:
function doAdd(iNum) {

  alert(iNum + 10);

}



document.write(doAdd.toString());

上のこのコードはdoAdd()関数のテキストを出力しました.