var funcName = new Function( [argname1, [... argnameN,]] body );
一般に、グローバル スコープ (スコープについては次のセクションで詳しく説明します) でオブジェクトを宣言することは、実際には属性に値を割り当てることに他なりません。グローバル オブジェクトは属性を追加するだけであり、属性名は add であり、属性の値はオブジェクト、つまり function(x, y){return x y;} であることを理解することが重要です。このステートメントの構文は次のとおりです。
のパラメータ JavaScript では、関数パラメータは非常に興味深いものです。たとえば、次のように関数が仮パラメータを指定せずに宣言されている場合でも、関数に任意の数のパラメータを渡すことができます。 🎜>
case "l":
s = s。 toLowerCase();
break;
default:
break;
}
adPrint(" ");
adPrint("Hello, world", 5);
adPrint("Hello, world", 5, "l");//小文字
adPrint("Hello, world", 5, "u" );//大文字
関数 adPrint は、宣言時に 3 つの仮パラメータ (出力する文字列、出力する長さ、大文字または小文字のどちらに変換するか) を受け入れます。ただし、呼び出すときは、1 つのパラメータ、2 つのパラメータ、または 3 つのパラメータを順に adPrint に渡すことができます (3 つ以上のパラメータを渡すこともできますが、それは問題ではありません)。実行結果は次のとおりです:
Hello , world
Hello
hello
HELLO
実際、JavaScript が関数パラメータを処理するとき、インタプリタが関数に渡すものは他のコンパイル言語とは異なります。配列の内部値は引数と呼ばれ、関数オブジェクトの生成時に初期化されます。たとえば、1 つのパラメータを adPrint に渡すと、他の 2 つのパラメータは未定義になります。このようにして、これらの未定義のパラメータを adPrint 関数内で処理し、外部に公開することができます。つまり、任意のパラメータを処理できます。
この魔法の引数については、別の例を通して説明します。
関数 sum(){
var result = 0;
for(var i = 0, len = argument.length; i
var current = argument [i];
if(isNaN(current)){
throw new Error("数値ではない例外");
}else{
}
}
結果を返します;
}
print(sum(10, 20, 30, 40, 50));
print(sum(4, 8, 15, 16) , 23, 42));//「Lost」の魔法の数字列
print(sum("new"));
関数 sum には明示的な仮パラメータがなく、動的に次のことができます。任意の数のパラメータを渡します。それでは、sum 関数でこれらのパラメータを参照するにはどうすればよいでしょうか。実行結果は次のとおりです。 🎜>エラー: 数値例外ではありません
関数スコープ
スコープの概念は、ほとんどすべての主流言語に反映されています。JavaScript では、変数スコープは以下の範囲内で有効です。ブロックスコープのない関数本体 Java 言語では、次のように for ループブロックで添字変数を定義できます:
public void method(){
for( int i = 0; i < ; obj1.length; i ){
//ここで何かをします;
//この時点では i は未定義です
for(int i = 0; i
//何か他のことをします;
}
}
JavaScript では:
コードをコピーします
コードは次のとおりです:JavaScript 関数はローカル スコープで実行されます。ローカル スコープで実行される関数本体は、その外部 (おそらくグローバル スコープ) の変数と関数にアクセスできます。 JavaScript のスコープは字句スコープです。いわゆる字句スコープとは、次の例のように、スコープが実行時ではなく定義 (字句解析) 時に決定されることを意味します。 >
コードをコピーします
コードは次のとおりです:
var str = "global";
functionscopeTest(){
print ( str);
var str = "ローカル"
} scopeTest();
実行結果は何ですか? 初心者は次のような答えを得る可能性があります:
グローバル
ローカル
そして、正しい結果は次のようになります:
未定義
local
関数scopeTestの定義では、事前に未宣言の変数strにアクセスしてからstr変数を初期化しているため、最初のprint(str)では未定義のエラーが返されます。では、この時点で関数が外部 str 変数にアクセスしないのはなぜでしょうか。これは、字句解析が完了した後、スコープ チェーンを構築するときに、関数内で定義された var 変数がチェーンに組み込まれるためです。関数全体では、scopeTest はすべて表示されます (関数本体の最初の行から最後の行まで)。 str 変数自体が未定義であるため、プログラムは順番に実行され、最初の行で未定義を返します。 value を str に設定するため、行の 3 行目の print(str) は「local」を返します。
関数コンテキスト
Java や C/C などの言語では、メソッド (関数) はオブジェクトに付属してのみ存在でき、独立していません。 JavaScript では、関数もオブジェクトであり、他のオブジェクトの一部ではありません。これを理解することは、特に関数型 JavaScript を理解する上で重要です。
関数のコンテキストは変更される可能性があるため、関数内では、あるオブジェクトのメソッドとして使用することも、別のオブジェクトのメソッドとして同時に使用することもできます。関数自体は独立しています。関数のコンテキストは、Function オブジェクトの call または apply 関数を通じて変更できます。
call および apply
call および apply は通常、コンテキストを変更するために使用されます。関数の this ポインターは、call または apply の最初のパラメーターに置き換えられます。「JavaScript 入門と JSON」の例を参照してください。
// という名前の人物を定義します。 jack
var jack = {
name : "jack",
age : 26
}
//abruzzi という名前の別の人を定義します
var abruzzi = {
name : "abruzzi",
age : 26
}
//グローバル関数オブジェクトを定義します
function printName(){
return this.name; }
//printName のコンテキストを jack に設定します。この時点では jack
print(printName.call(jack));
//printName のコンテキストを abruzzi に設定します。現時点では、これは abruzzi
print(printName.call(abruzzi));
print(printName.apply(jack));
print(printName.apply(abruzzi)); >パラメータが 1 つだけの場合 パラメータが複数ある場合でも、call と apply の使い方は同じです。
setName.apply(jack, ["Jack Sept."]); .apply(jack));
setName.call(abruzzi, "John Abruzzi");
print(printName.call(abruzzi));
Jack Sept.
John Abruzzi
apply の 2 番目のパラメーターは関数に必要なパラメーターの配列ですが、call にはカンマ (,) で区切られた複数のパラメーターが必要です。
関数の使い方
前述の通り、JavaScript では関数を変数に代入することができます
◆ オブジェクトのプロパティに代入
◆ パラメータとして他の関数に渡される
◆ 関数の結果として返される
これらのシナリオをそれぞれ見てみましょう:
変数に値を代入する:
// 2 つのパラメータを受け取り、その合計を返す関数を宣言します
function add(x, y){
return x y
}
var a = 0;
a = add;//関数を変数に代入します
var b = a(2, 3);//この新しい関数を呼び出します
print(b);代入後、変数 a が関数 add を参照するため、「5」が出力されます。つまり、 a の値は関数オブジェクト (実行可能なコード ブロック) であるため、 a(2 のようなステートメントを使用できます) 、3) は合計演算を実行するために使用されます。
はオブジェクトの属性に割り当てられます:
コードをコピーします
コードは次のとおりです:
var obj = { id : "obj1" } obj.func = add;//obj オブジェクトの属性に値を割り当てます obj.func(2, 3);// 5 を返します
実際、この例は本質的に前の例と同じです。最初の例の変数は、実際にはグローバル オブジェクトのプロパティです (クライアント環境にある場合は、ウィンドウ オブジェクトとして表されます)。 2 番目の例は obj オブジェクトです。グローバル オブジェクトを直接参照することはほとんどないため、個別に説明します。
はパラメータとして渡されます:
//高度な印刷関数の 2 番目のバージョン
function adPrint2(str, handler){
print(handler(str));
//文字列を大文字に変換して return
function up(str){
return str.toUpperCase();
}
/ /文字列を次のように変換します小文字で return
function low(str){
return str.toLowerCase();
}
adPrint2("Hello, world", up) ; , world", low);
このスニペットを実行すると、次の結果が得られます:
HELLO, WORLD
hello, world
は、関数の 2 番目のパラメーターであることに注意してください。 adPrint2 は実際には関数です。この処理関数がパラメーターとして渡された場合でも、この関数は adPrint2 内で呼び出すことができます。特に、いくつかのオブジェクトを処理したいが、その内容がわからない場合に便利です。形式では、「処理メソッド」を抽象的な粒度 (つまり、関数) としてラップできます。
を関数の戻り値として使用します:
最初に最も単純な例を見てみましょう:
return function(){ print("curring")
}
}
関数カレーリングは匿名関数を返します。この匿名関数は単にcurring()を呼び出すと次の結果を取得します:
print("curring") }
Ifカリー化によって返された匿名を呼び出したい場合は、次のようにする必要があります:
currying()();
最初の括弧操作は、カリー化自体を呼び出すことを意味します。 2 番目のブラケット演算子がこの戻り値を呼び出すと、次のような結果が得られます:
curry