関数の定義は大きく 3 つの方法に分けることができます:
1 つ目: これも最も一般的な方法です
function double(x){ return 2 * x; }
2 つ目: このメソッドは Function コンストラクターを使用し、パラメーター リストと関数本体の両方を次のように受け取ります文字列は非常に不便なので、使用はお勧めしません。
var double = new Function('x', 'return 2 * x;');
3 番目のタイプ:
var double = function(x) { return 2* x; }
「=」の右側の関数は、関数を作成した後、変数 square に代入されることに注意してください。
匿名関数の作成
最初の方法: 上で述べたように二乗関数を定義します。これも最も一般的に使用される方法の 1 つです。
2 番目の方法:
(function(x, y){ alert(x + y); })(2, 3);
ここ (最初の括弧内) で匿名関数が作成され、2 番目の括弧を使用して匿名関数を呼び出し、パラメーターを渡します。括弧は式であり、式には戻り値があるため、最後に括弧のペアを追加して実行させることができます
1. 自己実行匿名関数とは何ですか。 function?
これは次のような関数を指します: (function {// code})();2. 質問
function {// code})(); が実行できるのはなぜですか。 / code} (); しかし、エラーが報告されますか? 3. 分析 (1) まず、この 2 つの違いを理解する必要があります:
(関数 {// コード}) は式、関数 { // code} は関数宣言です。
(2) 次に、js の「プリコンパイル」の特徴:
「プリコンパイル」段階では、js は関数宣言を解釈しますが、
の場合は無視されます。 function() {// code}(); に対して実行されます。function() {//code} は「コンパイル前」段階で解釈されているため、js は function(){//code} をスキップして実行を試みます(); なのでエラーが報告されます ;
js が (function {// code})(); を実行すると、(function {// code}) は式であるため、js はそれを解決して戻り値を取得します。戻り値は関数なので、(); が見つかった場合、それが実行されます
また、関数を式に変換する方法は、必ずしもグループ化演算子 () に依存するわけではありません。 void 演算子、~ 演算子、! 演算子...…
例:
!function(){ alert("另类的匿名函数自执行"); }();
function checkClosure(){ var str = 'rain-man'; setTimeout( function(){ alert(str); } //这是一个匿名函数 , 2000); } checkClosure();
function forTimeout(x, y){ alert(x + y); } function delay(x , y , time){ setTimeout('forTimeout(' + x + ',' + y + ')' , time); } /** * 上面的delay函数十分难以阅读,也不容易编写,但如果使用闭包就可以让代码更加清晰 * function delay(x , y , time){ * setTimeout( * function(){ * forTimeout(x , y) * } * , time); * } */
var oEvent = {}; (function(){ var addEvent = function(){ /*代码的实现省略了*/ }; function removeEvent(){} oEvent.addEvent = addEvent; oEvent.removeEvent = removeEvent; })();
var rainman = (function(x , y){ return x + y; })(2 , 3); /** * 也可以写成下面的形式,因为第一个括号只是帮助我们阅读,但是不推荐使用下面这种书写格式。 * var rainman = function(x , y){ * return x + y; * }(2 , 3);
var outer = null; (function(){ var one = 1; function inner (){ one += 1; alert(one); } outer = inner; })(); outer(); //2 outer(); //3 outer(); //4
/** * <body> * <ul> * <li>one</li> * <li>two</li> * <li>three</li> * <li>one</li> * </ul> */ var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ lists[ i ].onmouseover = function(){ alert(i); }; }
要素上に移動すると、期待していた要素の添字ではなく、常に 4 が表示されます。どうしてこれなの?注意事項(最終値)に記載済みです。明らかに、この説明は単純すぎます。mouseover イベントが listen 関数を呼び出すと、まず匿名関数 (function(){alert(i); }) 内を検索して、i が定義されているかどうかを確認します。 ; したがって、上方向に検索して検索します。結果は定義されており、i の値は 4 (ループ後の i の値) であるため、最終的には毎回 4 が表示されます。
解決策 1:
var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ (function(index){ lists[ index ].onmouseover = function(){ alert(index); }; })(i); }
解決策 2:
var lists = document.getElementsByTagName('li'); for(var i = 0, len = lists.length; i < len; i++){ lists[ i ].$$index = i; //通过在Dom元素上绑定$$index属性记录下标 lists[ i ].onmouseover = function(){ alert(this.$$index); }; }
2 メモリ リーク