ホームページ > 記事 > ウェブフロントエンド > 時間があるときに JS に関するこの記事をお読みください
関数はモジュール型プログラミングの基礎です。複雑な Ajax アプリケーションを作成するには、関数をより深く理解する必要があります。
JavaScriptの関数は他の言語とは異なり、各関数はオブジェクトとして保持され、実行されます。関数オブジェクトのプロパティを使用すると、関数を変数に割り当てたり、関数をパラメーターとして渡すことが簡単にできます。続行する前に、関数を使用するための構文を見てみましょう:
以下は引用部分です:
function func1(…){…} var func2=function(…){…}; var func3=function func4(…){…}; var func5=new Function();
これらは、関数を宣言するための正しい構文です。これらは、他の言語の一般的な関数や、以前に紹介した関数の定義方法とは大きく異なります。では、なぜ JavaScript でこのように記述できるのでしょうか?それはどのような構文に従いますか?これらについては以下で説明します。
関数オブジェクトを理解する
functionキーワードを使用して関数を定義し、各関数に関数名を指定し、関数名を通じて呼び出すことができます。 JavaScript が解釈されて実行されるとき、関数はオブジェクトとして保持されます。これが、導入される Function オブジェクトです。
関数オブジェクトは他のユーザー定義オブジェクトとは本質的に異なります。このタイプのオブジェクトは内部オブジェクトと呼ばれます。たとえば、日付オブジェクト (Date)、配列オブジェクト (Array)、および文字列オブジェクト (String) はすべて内部オブジェクトです。 。これらの組み込みオブジェクトのコンストラクターは JavaScript 自体によって定義されます。 new Array() などのステートメントを実行してオブジェクトを返すことにより、JavaScript にはユーザーがオブジェクトの構築方法を指定する代わりに、返されたオブジェクトを初期化する内部メカニズムがあります。 。
JavaScriptでは、配列オブジェクトの対応する型がArrayで、日付オブジェクトの対応する型がDateであるのと同じように、関数オブジェクトの対応する型はFunctionです。 new Function()を通じて関数オブジェクトを作成することもできます。 function キーワードを使用してオブジェクトを作成します。理解を容易にするために、関数オブジェクトの作成と配列オブジェクトの作成を比較します。まず配列オブジェクトを見てみましょう: 次の 2 行のコードは両方とも配列オブジェクト myArray を作成します:
以下は参照フラグメントです:
var myArray=[]; //等价于 var myArray=new Array();
同様に、次の 2 行のコードも関数 myFunction を作成します:
function myFunction(a,b){ return a+b; } //等价于 var myFunction=new Function("a","b","return a+b");
ステートメントを比較すると、関数オブジェクトの本質が明確にわかります。インタプリタ内でこの構文が出現すると、関数オブジェクトは上記のコードの最初の方法になります。関数は内部オブジェクトとして自動的に構築され、実行されます。ここから、関数オブジェクト名 (関数変数) と通常の変数名は同じ仕様であることがわかります。どちらも変数名を通じて変数を参照できますが、関数変数名の後に括弧とパラメーターを続けることができます。転送機能を実行するリスト。
new Function() の形式で関数を作成することは一般的ではありません。関数本体に複数のステートメントが含まれている場合、それらを文字列の形式でパラメータとして渡すと、コードの可読性が悪くなります。以下はその使用構文の紹介です:
以下は引用部分です:
var funcName=new Function(p1,p2,...,pn,body);
パラメータの型はすべて文字列です。 p1 から pn は作成された関数のパラメータ名のリストを表し、body は関数本体のステートメントを表します。 funcName は作成された関数の名前です。パラメーターを指定せずに空の関数を作成したり、funcName を指定せずに名前のない関数を作成したりすることもできます。もちろん、そのような関数には意味がありません。
p1 から pn はパラメータ名のリストであることに注意してください。つまり、p1 はパラメータを表すだけでなく、カンマ区切りのパラメータ リストにすることもできます。たとえば、次の定義は同等です。以下は引用スニペットです:
new Function("a", "b", "c", "return a+b+c") new Function("a, b, c", "return a+b+c") new Function("a,b", "c", "return a+b+c")
JavaScript は Function タイプを導入し、new Function() などの構文を提供します。これは、関数オブジェクトがプロパティとメソッドを追加するために Function タイプを使用する必要があるためです。
関数の本質は内部オブジェクトであり、それがどのように動作するかはJavaScriptインタプリタによって決まります。上記のコードで作成した関数は、プログラム内で関数名を使用して呼び出すことができます。このセクションの冒頭に挙げた関数定義の問題についても説明します。関数宣言の直後に括弧を追加して、関数が作成直後に呼び出されることを示すことができることに注意してください。例:
以下は引用部分です:
var i=function (a,b){ return a+b; }(1,2); alert(i);
このコードは、変数 i の値が次と等しいことを示します。 3. i は、作成された関数ではなく戻り値を表します。これは、括弧 "(" が等号 "= よりも優先順位が高いためです。このようなコードは一般的には使用されないかもしれませんが、ユーザーが使用したい場合にはこれがモジュラーの良い解決策です。
関数を作成する次の 2 つの方法は同等であることに注意してください:
以下は引用です:
function funcName(){ //函数体 } //等价于 var funcName=function(){ //函数体 }
しかし、前の 1 つの方法は、名前付き関数を作成することです。名前のない関数を作成する場合は、変数に名前のない関数を指すようにするだけです。名前のない関数の場合は、呼び出してから定義する必要があります。例:
以下は参照フラグメントです:
<script language="JavaScript" type="text/javascript"> <!-- func(); var func=function(){ alert(1) } //--> </script>
このステートメントは func に対して未定義エラーを生成します:
以下は参照フラグメントです:
<script language="JavaScript" type="text/javascript"> <!-- func(); function func(){ alert(1) } //--> </script>
则能够正确执行,下面的语句也能正确执行:
以下是引用片段:
<script language="JavaScript" type="text/javascript"> <!-- func(); var someFunc=function func(){ alert(1) } //--> </script>
由此可见,尽管JavaScript是一门解释型的语言,但它会在函数调用时,检查整个代码中是否存在相应的函数定义,这个函数名只有是通过function funcName()形式定义的才会有效,而不能是匿名函数。
函数对象和其他内部对象的关系
除了函数对象,还有很多内部对象,比如:Object、Array、Date、RegExp、Math、Error。这些名称实际上表示一个类型,可以通过new操作符返回一个对象。然而函数对象和其他对象不同,当用typeof得到一个函数对象的类型时,它仍然会返回字符串“function”,而typeof一个数组对象或其他的对象时,它会返回字符串“object”。下面的代码示例了typeof不同类型的情况:
以下是引用片段:
alert(typeof(Function))); alert(typeof(new Function())); alert(typeof(Array)); alert(typeof(Object)); alert(typeof(new Array())); alert(typeof(new Date())); alert(typeof(new Object()));
运行这段代码可以发现:前面4条语句都会显示“function”,而后面3条语句则显示“object”,可见new一个function实际上是返回一个函数。这与其他的对象有很大的不同。其他的类型Array、Object等都会通过new操作符返回一个普通对象。尽管函数本身也是一个对象,但它与普通的对象还是有区别的,因为它同时也是对象构造器,也就是说,可以new一个函数来返回一个对象,这在前面已经介绍。所有typeof返回“function”的对象都是函数对象。也称这样的对象为构造器(constructor),因而,所有的构造器都是对象,但不是所有的对象都是构造器。
既然函数本身也是一个对象,它们的类型是function,联想到C++、Java等面向对象语言的类定义,可以猜测到Function类型的作用所在,那就是可以给函数对象本身定义一些方法和属性,借助于函数的prototype对象,可以很方便地修改和扩充Function类型的定义,例如下面扩展了函数类型Function,为其增加了method1方法,作用是弹出对话框显示"function":
以下是引用片段:
Functiothod1=function(){ alert("function"); } function func1(a,b,c){ return a+b+c; } func1.method1(); functhod1();
注意最后一个语句:funchotd1(),它调用了method1这个函数对象的method1方法。虽然看上去有点容易混淆,但仔细观察一下语法还是很明确的:这是一个递归的定义。因为method1本身也是一个函数,所以它同样具有函数对象的属性和方法,所有对Function类型的方法扩充都具有这样的递归性质。