ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript関数オブジェクトの作成、パラメータ、スコープインスタンスの詳細な説明
関数オブジェクト
1.1 関数の作成
JavaScript 関数を作成するためのあまり使用されていない (ほとんど誰も使用していない) 方法は、関数の「コンストラクター」で new 演算子を使用することです:
var funcName = new Function( [argname1, [... argnameN,]] body );
パラメーター リストには任意の値を含めることができますパラメータの数とその後に関数本体が続きます。例:
var add = new Function("x", "y", "return(x+y)"); print(add(2, 4));
は結果を出力します:
6
しかし、関数本体がより複雑であれば、誰がこのような使いにくい方法で関数を作成するでしょうか?これには多大な労力がかかるため、JavaScript はリテラルを通じて関数を作成するための一種の糖衣構文を提供しています:
function add(x, y){ return x + y; }
または:
var add = function(x, y){ return x + y; }
実際、このような糖衣構文により、従来の分野のプログラマーにとって誤解が生じます。 function キーワードは Function を呼び出して新しいオブジェクトを作成し、パラメーター リストと関数本体を Function のコンストラクターに正確に渡します。
一般的に言えば、グローバル スコープ (スコープについては次のセクションで詳しく説明します) でオブジェクトを宣言することは、プロパティに値を割り当てることに他なりません。たとえば、上記の例の add 関数は、実際には値を追加するだけです。グローバル オブジェクト、属性名は add、属性の値はオブジェクト、つまり function(x, y){return x+y;} であることを文法的に理解することが重要です。と同じ:
var str = "This is a string";
へ。これらはすべて、グローバル オブジェクトに新しい属性を動的に追加するだけです。
関数が他のオブジェクトと同様に、独立したオブジェクトとして JavaScript 実行システムに存在することを説明するには、次の例を見てみましょう:
function p(){ print("invoke p by ()"); } p.id = "func"; p.type = "function"; print(p); print(p.id+":"+p.type); print(p());
その通りです。p は匿名関数 (オブジェクト) を指しますが、At です。同時に、他のオブジェクトと同様に、属性を持つこともできます。実行結果は次のとおりです。
function (){ print("invoke p by ()"); } func:function invoke p by ()
1.2 関数のパラメーター
JavaScript では、関数のパラメーターは非常に興味深いものです。たとえば、任意の数の関数を渡すことができます。関数の宣言時に仮パラメータが指定されていない場合でも、次のように関数にパラメータを追加できます。
function adPrint(str, len, option){ var s = str || "default"; var l = len || s.length; var o = option || "i"; s = s.substring(0, l); switch(o){ case "u": s = s.toUpperCase(); break; case "l": s = s.toLowerCase(); break; default: break; } print(s); } adPrint("Hello, world"); adPrint("Hello, world", 5); adPrint("Hello, world", 5, "l");//lower case adPrint("Hello, world", 5, "u");//upper case
関数 adPrint は、宣言時に 3 つの仮パラメータを受け入れます: 出力する文字列、出力する長さ、および出力するかどうか大文字と小文字のマーカーに変換します。ただし、呼び出すときは、1 つのパラメーター、2 つのパラメーター、または 3 つのパラメーターを順に adPrint に渡すことができます (3 つ以上のパラメーターを渡すこともできますが、それは問題ではありません)。実行結果は次のとおりです。実際、JavaScript が関数パラメータを処理する場合、他のコンパイル言語とは異なり、インタープリタが関数に渡すのは、関数オブジェクトの生成時に初期化される引数と呼ばれる配列のような内部値です。たとえば、1 つのパラメータを adPrint に渡すと、他の 2 つのパラメータは未定義になります。このようにして、これらの未定義のパラメータを adPrint 関数内で処理し、外部に公開できます。つまり、任意のパラメータを処理できます。
この魔法の引数については別の例で説明します:
Hello, world Hello hello HELLO
function sum(){ var result = 0; for(var i = 0, len = arguments.length; i < len; i++){ var current = arguments[i]; if(isNaN(current)){ throw new Error("not a number exception"); }else{ result += current; } } return result; } print(sum(10, 20, 30, 40, 50)); print(sum(4, 8, 15, 16, 23, 42));//《迷失》上那串神奇的数字 print(sum("new"));
関数スコープ
JavaScript では、スコープの概念が独自の特徴を持っています。 JavaScript は、ブロック スコープなしで関数本体内で有効です。 Java 言語では、次のように for ループ ブロックで添え字変数を定義できます。
150 108 Error: not a number exception
public void method(){ for(int i = 0; i < obj1.length; i++){ //do something here; } //此时的i为未定义 for(int i = 0; i < obj2.length; i++){ //do something else; } }JavaScript 関数はローカル スコープで実行されます。ローカル スコープで実行される関数本体は、その外部 (おそらくグローバル スコープ) の変数と関数にアクセスできます。 JavaScript のスコープは字句スコープです。つまり、そのスコープは実行時ではなく、定義 (字句解析) 時に決定されます。 例:
function func(){ for(var i = 0; i < array.length; i++){ //do something here. } //此时i仍然有值,及I == array.length print(i);//i == array.length; }
初心者は次のようになります。この答えを得る:
var str = "global"; function scopeTest(){ print(str); var str = "local"; print(str); } scopeTest();
そして、正しい結果は次のようになります:
global local
なぜなら、関数scopeTestの定義では、宣言されていない変数strに事前にアクセスし、その後にstr変数にアクセスするため、初期化が実行されるため、最初のprint(str) は未定義のエラーを返します。では、この時点で関数が外部 str 変数にアクセスしないのはなぜでしょうか。これは、字句解析が完了した後、スコープ チェーンを構築するときに、関数内で定義された var 変数がチェーンに組み込まれるためです。関数全体では、scopeTest はすべて表示されます (関数本体の最初の行から最後の行まで)。 str 変数自体が未定義であるため、プログラムは順番に実行され、最初の行で未定義を返します。 value を str に設定するため、行の 3 行目の print(str) は「local」を返します。
以上がJavaScript関数オブジェクトの作成、パラメータ、スコープインスタンスの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。