JavaScriptの語法の作用の領域と閉鎖を深く理解します.
41474 ワード
包みを閉じる
クローズドの定義について:A closure is the commbination of a function and the lexical environment within which that function was declead.–MDN A closure is the local variables for a function-kept alive after the funcer the function hanced.japtection.jancevanced.
語法のスコープ(lexical environment)
スコープチェーン:関数の実行中に、まず自分の内部から変数を探します. もし見つけられなかったら、現在の関数を作成するスコープからこれを探してwindow まで上げます.注意して探しているのは変数の現在の状態 です.
語法のスコープを深く理解する
関連概念
実行コンテキスト(execution Contect)
アクティブオブジェクトAO:関数の内部に作成された変数や関数のパラメータなどが、関数が呼び出されたときに作成されます.
[Scope]属性:活動対象から見つからないときはScopeから関数を探します.宣言時には[Scope]属性を作成し、この関数の語法作用領域を含む作用ドメインチェーンをscope属性に保存します.関数を呼び出す時は実行コンテキスト、すなわち実行環境を作成し、コピー関数の[Scope]を通じて属性のオブジェクトは、関数として作用するドメインチェーンを構築します.
コードの理解:
JavaScriptアドバンストプログラムの設計定義:クローズドは別の関数のスコープにアクセスする変数の関数です.
ブラウザ回収メカニズムGCメカニズムから、クローズドを理解する:
JavaScriptでは、オブジェクトがもう引用されないと、このオブジェクトはGCによって回収されます.2つのオブジェクトが相互に参照され、第三者によって参照されない場合は、この2つのオブジェクトも回収されます.この時、関数aは関数bによって参照され、bはa以外のc(つまり第三者)によって参照され、関数aが実行された後は回収されない.同じように、その内部の関数bも内部の変数は回収されないし、回収されない.これはパッケージデータと一時保存データの目的を果たした.また、参照された関数bと、この関数bの品詞作用領域、すなわち作用ドメインチェーンの組み合わせは、クローズドとなる.
閉包の役割
パッケージデータ一時保存データ
閉包式の例
つまり、関数carの内部関数fnが関数car以外の変数によって参照されると、クローズドパケットが作成される.
閉包に関する判例理解:
[01]次のコードの出力はどれぐらいですか?もし3を出力したいなら、コードはどうやって改造しますか?
関数コリゼーション-関数の一部のパラメータだけに渡して呼び出して、残りのパラメータを処理するための関数を返します.
sum関数を書いて、次のような呼び方を実現します.
クローズドの定義について:A closure is the commbination of a function and the lexical environment within which that function was declead.–MDN A closure is the local variables for a function-kept alive after the funcer the function hanced.japtection.jancevanced.
語法のスコープ(lexical environment)
スコープチェーン:
語法のスコープを深く理解する
関連概念
実行コンテキスト(execution Contect)
アクティブオブジェクトAO:関数の内部に作成された変数や関数のパラメータなどが、関数が呼び出されたときに作成されます.
[Scope]属性:活動対象から見つからないときはScopeから関数を探します.宣言時には[Scope]属性を作成し、この関数の語法作用領域を含む作用ドメインチェーンをscope属性に保存します.関数を呼び出す時は実行コンテキスト、すなわち実行環境を作成し、コピー関数の[Scope]を通じて属性のオブジェクトは、関数として作用するドメインチェーンを構築します.
コードの理解:
var test = 0;
function createCompareFunction(property) {
return function (object1,object2) {
var value1 = object1[property];
var value2 = object2[property];
if(value1 > value2) {
return value1;
}else if(value1 < value2) {
return value2;
}else {
return 0;
}
}
}
var compare = createCompareFunction("age");
compare({"age":10},{"age":20});//20
理解: createCompareFunction
globalContext = {
AO: {
x : 10,
createCompareFunction: function,
compare : undefined
}
Scope: null
}
createCompareFunctionContext.[[Scope]] = globalContext
createCompareFunctionContext = { //createCompareFunction
AO:{
property:'age',
argumets:'age'
},
Scope:{
globalContext
}
}
// createCompareFunction
Context = {
AO: {
object1 : {age:10},
object2 : {age:20},
argumets: [{age:10},{age:20}]
},
Scope:{
arguments:{"age"},
property : 'age',
createCompareFunction.[[Scope]] : globalContext
}
}
AO ,
[[Scope]]
[[Scope]] 。
[[Scope]] createCompareFunction
。
閉包とは何ですかJavaScriptアドバンストプログラムの設計定義:クローズドは別の関数のスコープにアクセスする変数の関数です.
function a() {
var j;
function b(){
return j;
}
return b;
}
var c = a();
console.log(c());
つまり、関数bは外部関数cによって引用されるので、関数bはaの活動対象を引用します.aの活動対象はまだ引用されているので、廃棄されません.ですから、aの活動対象内の変数などを間接的に保存しました.外部関数は、関数aの関連データを参照して、aのアクティブオブジェクト中の関連データを一時保存することができる.ブラウザ回収メカニズムGCメカニズムから、クローズドを理解する:
JavaScriptでは、オブジェクトがもう引用されないと、このオブジェクトはGCによって回収されます.2つのオブジェクトが相互に参照され、第三者によって参照されない場合は、この2つのオブジェクトも回収されます.この時、関数aは関数bによって参照され、bはa以外のc(つまり第三者)によって参照され、関数aが実行された後は回収されない.同じように、その内部の関数bも内部の変数は回収されないし、回収されない.これはパッケージデータと一時保存データの目的を果たした.また、参照された関数bと、この関数bの品詞作用領域、すなわち作用ドメインチェーンの組み合わせは、クローズドとなる.
閉包の役割
パッケージデータ一時保存データ
閉包式の例
function car(){
var speed = 0 /
function fn(){
speed++
console.log(speed)
} / fn spedd
return fn
}
var speedUp = car()
speedUp() //1
speedUp() //2
変数は一時的に保存できます.変数は破壊されません.つまり、関数carの内部関数fnが関数car以外の変数によって参照されると、クローズドパケットが作成される.
閉包に関する判例理解:
[01]次のコードの出力はどれぐらいですか?もし3を出力したいなら、コードはどうやって改造しますか?
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i
};
}
console.log( fnArr[3]() ) // 10
なぜ10で、3ではないですか?fnArr[i] = function(){
return i;
}; fnArr[i] return i i
:
fnArr[3] = function(){
return i;
}
fnArr[3] = function(){
return 3;
}
クローズド改造:01:
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = (function(j){
return function(){
return j
}
})(i)
}
console.log( fnArr[3]() ) // 3 10
// 10 10 10
理解するvar fnArr = [];
for(var i = 0;i<10;i++) {
fnArr[i] = (function(j){
return function(){
return j;
}
})(i);
}
function a(i) {
var j = i;
function b(){
return j;
// j 。 j
}
return b;
}
var c = a(); // (function(j){})(i)
c(); // fnArr[i]() fnArr[i] b
02:
for(var i = 0;i<10;i++) {
(function (j) {
fnArr[j] = function () {
console.log(j);
}
})(i)
}
fnArr[3]();
03: ES6
var fnArr = []
for (let i = 0; i < 10; i ++) { //let es6
fnArr[i] = function(){
return i
}
}
console.log( fnArr[3]() ) // 3
[02]Casオブジェクトをパッケージ化する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() //30
// speed
[03]次のコードの出力はどれぐらいですか?どのように連続して0、1、2、3、4を出力しますか?for(var i=0; i<5; i++){
setTimeout(function(){
console.log('delayer:' + i )
}, 0)
}
// setTimeout
// i 5 i
クローズドの変更:for(var i=0; i<5; i++){
(function(j){
setTimeout(function(){
console.log('delayer:' + j )
}, 0)
})(i)
}
for(var i=0; i<5; i++){
setTimeout((function(j){
return function(){
console.log('delayer:' + j )
}
}(i)), 0)
}
[04]次のコードの出力はどれぐらいですか?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() ) // ? 2
console.log( counter2() ) // ? 3
[05]補完コードで、配列は名前、年齢、任意のフィールドで並べ替えられます.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')) field
関数コリック化関数コリゼーション-関数の一部のパラメータだけに渡して呼び出して、残りのパラメータを処理するための関数を返します.
sum関数を書いて、次のような呼び方を実現します.
console.log( sum(1)(2) ) // 3
console.log( sum(5)(-1) ) // 4
function sum(a) {
return function(b) {
return a + b
}
}