この記事の内容は、js クロージャのコード例を説明するものです。必要な方は参考にしていただければ幸いです。
正確には、クロージャは通常のガベージ コレクション処理メカニズムに基づいています。言い換えれば、一般に、関数 (関数スコープ) が実行された後、その中で宣言されたすべての変数はガベージ コレクターによって解放され、リサイクルされます。ただし、クロージャーは、関数の実行後にスコープ内の変数を保存し、ガベージ コレクションを行わないようにするトリックを使用します。
クロージャ
定義MDN定義
javascriptkit
字句スコープ
スコープチェーン関数の実行中、最初にできることは自分自身の中から変数を見つけるのではなく、現在の関数が作成されるスコープ (字句スコープ) から変数を探す必要があります。
スコープ チェーン ブログ
関数は、そのスコープ チェーン内で探している変数とともにクロージャを形成します
一般に、クロージャは主にデータをカプセル化するために使用されます
一時データ
典型的なクロージャのケース
function car(){ var speed = 0 function fn(){ speed++ console.log(speed) } return fn } var speedUp = car() speedUp() //1 speedUp() //2
次のコードが関数内で実行されない場合
function fn(){ speed++ console.log(speed) } return fn
コードの実行が完了した後、内部で関数 ローカル変数 SpeedUp は常に存在するため (現在のページが閉じられない限り、グローバル変数は常に存在します)、関数内のスコープは破棄できません。これは、ブラウザのガベージ コレクション メカニズムと同様です。speedUp() を実行すると、関数の字句スコープ内で検索が行われ、関数内で fn が返されるため、クロージャを形成できます。単純に
var speed = 0 function fn(){ speed++ console.log(speed) }
として理解されます。このコード部分はクロージャを形成します。fn が返されない場合、関数内のローカル変数は破棄されます。
即時実行ステートメントと即時実行関数を使用して、上記のコードがどのように進化するかを見てみましょう:
function car(){ var speed = 0 function fn(){ speed++ console.log(speed) } return fn } var speedUp = car() //1 function car(){ var speed = 0 return function (){ speed++ console.log(speed) } } var speedUp = car() //2 function car(speed){ return function (){ speed++ console.log(speed) } } var speedUp = car(3) //3 function car(){ var speed = arguments[0] return function (){ speed++ console.log(speed) } } var speedUp = car() //4 function car(){ var speed = 0 return function (){ speed++ console.log(speed) } } //5 car可以不写,则为匿名函数 var speedUp = (function car(speed){ return function (){ speed++ console.log(speed) } } )(3)
次のコードの出力はどれくらいですか? 3を出力したい場合、コードをどのように修正すればよいでしょうか?
var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i }; } console.log( fnArr[3]() ) // 10
均等進化
ループのレベルが 2 つだけであると仮定します。
var fnArr = [] for (var i = 0; i < 2; i ++) { fnArr[i] = (function(j){ return function(){ return j } })(i) } fnArr[3]() //1 var fnArr = [] fnArr[0] = (function(j){ return function(){ return j } })(0) } fnArr[1] = (function(j){ return function(){ return j } })(1) } fnArr[3]() //2 var a = (function(j){ return function(){ return j } })(0) } var b = (function(j){ return function(){ return j } })(1) } b() //3 var a = (function(j){ return function(){ return j } })(0) } function fn2(j){ return function(){ return j } } var b = fn2(1) //4 var a = (function(j){ return function(){ return j } })(0) } function fn2(j){ return function(){ return j } return f } var b = fn2(1) //5 var a = (function(j){ return function(){ return j } })(0) } function fn2(j){ var j = arguments[0] function f(){ return j } return f } var b = fn2(1)
変換後 (ステートメントの即時実行、進化プロセス)
var fnArr = [] for (var i = 0; i < 10; i ++) { fnArr[i] = (function(j){ return function(){ return j } })(i) } console.log( fnArr[3]() ) // 3 var fnArr = [] for (var i = 0; i < 10; i ++) { (function(i){ fnArr[i] = function(){ return i } })(i) } console.log( fnArr[3]() ) // 3 var fnArr = [] for (let i = 0; i < 10; i ++) { fnArr[i] = function(){ return i } } console.log( fnArr[3]() ) // 3
Encapsulate Car オブジェクト
var Car = (function(){ var speed = 0; function set(s){ speed = s } function get(){ return speed } function speedUp(){ speed++ } function speedDown(){ speed-- } return { setSpeed: setSpeed, get: get, speedUp: speedUp, speedDown: speedDown } })() Car.set(30) Car.get() //30 Car.speedUp() Car.get() //31 Car.speedDown() Car.get() //3
次のコードの出力はいくらですか? 0,1,2,3,4
for(var i=0; i<5; i++){ setTimeout(function(){ console.log('delayer:' + i ) }, 0) }
を連続出力する方法 出力結果は、layer:5(5回連続出力)となります。 setTimeoutを実行すると、真ん中の部分でコードがハングします。 i のトラバースが完了するまでタスク キューを実行し、この時点で i = 5 が出力されるため、layer:5 が出力されます (5 回連続出力)
変更後
for(var i=0; i<5; i++){ (function(j){ setTimeout(function(){ console.log('delayer:' + j ) }, 0)//1000-1000*j })(i) }
or
for(var i=0; i<5; i++){ setTimeout((function(j){ return function(){ console.log('delayer:' + j ) } }(i)), 0) }
次のコードの出力はどれくらいですか?
function makeCounter() { var count = 0 return function() { return count++ }; } var counter = makeCounter() var counter2 = makeCounter(); console.log( counter() ) // 0 console.log( counter() ) // 1 console.log( counter2() ) // 0 console.log( counter2() ) // 1
配列を名前、年齢、および任意のフィールドで並べ替えるコードを完成させます
var users = [ { name: "John", age: 20, company: "Baidu" }, { name: "Pete", age: 18, company: "Alibaba" }, { name: "Ann", age: 19, company: "Tecent" } ] users.sort(byName) users.sort(byAge) users.sort(byField('company'))
回答
function byName(user1, user2){ return user1.name > user2.name } function byAge (user1, user2){ return user1.age > user2.age } function byFeild(field){ return function(user1, user2){ return user1[field] > user2[field] } } users.sort(byField('company'))
sum 関数を作成し、次の呼び出しメソッドを実装します
れー以上がjsクロージャのコード例解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。