ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript クロージャー関数の基本的な使用法と発生した問題の解決策

JavaScript クロージャー関数の基本的な使用法と発生した問題の解決策

不言
不言転載
2018-10-23 15:17:322245ブラウズ

この記事では、JavaScript クロージャ関数の基本的な使い方と、発生した問題の解決策について説明します。必要な方は参考にしてください。

面接中にいつもクロージャとは何かと聞かれましたが、これまであまり気にしていませんでした。他の関数の内部変数

を読み取ることができる関数。

つまり、本質的に、クロージャは関数の内部と関数の外部を接続する橋です。 (1) クロージャの最も基本的なアプリケーション:

少废话,上代码

还是<<javascript高级程序设计>>的栗子,
function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];

        if(value1 < value2) {
            return -1;
        } else if(value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    };
}
var compare = createComparisonFunction("name"); 

var result = compare({ name: "Nicholas" }, { name: "Greg" });
分析:
(1) クロージャ関数はその外部関数にアクセスできます

返される匿名関数はクロージャ関数ですの場合、外部関数にアクセスするこの匿名関数のアクティブ オブジェクトは、propertyName パラメーターです。外部スコープ チェーンはこの匿名関数に含まれているため (比較関数には

createComparisonFunction() 関数のアクティブ オブジェクトとグローバル変数オブジェクトが含まれているとも解釈できます)、返された匿名関数は常にその外部にアクセスできます。 propertyName とグローバル変数。

(2) クロージャによって参照される外部変数は、その変数が配置されているスコープの破棄によって破棄されません。

外部関数のアクティブなオブジェクトは、返されたクロージャ関数内で参照されるため、 createComparisonFunction() のアクティブ オブジェクト (つまり propertyName) は、createComparisonFunction() の実行後に破棄されません。 createComparisonFunction は実行後に実行環境内のスコープ チェーンを破棄しますが、そのアクティブ オブジェクトは引き続きクロージャ関数によって参照され、匿名関数の実行環境のスコープに配置されるためです。

( 2)クロージャ

(1)。クロージャは、それを含む関数内の変数の最後の値のみを取得できます。

        function createFunctions(){ 
            var result = new Array(); 
            for (var i=0; i < 10; i++){ 
                result[i] = function(){ 
                return i; 
                }; 
            } 
            return result; 
        }
        
        var res = createFunctions();
        console.log(res[0]());  //10
        console.log(res[1]());  //10
Principle:

各関数のアクティブなオブジェクトのためです。 createFunctions() 関数がそれらに格納されるため、それらはすべて同じ変数 i を参照します。 createFunctions() 関数が戻ると、変数 i の値は 10 になります。このとき、各関数は変数 i を保存する同じ変数オブジェクトを参照するため、各関数内の i の値は 10

になります。 :

获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
        function  createFunctions2(){
            var result  = new Array();
            for(var i = 0 ; i <10 ; i++){
                result[i] = (function(num){
                    return function(){
                        return num
                    }
                })(i)
            }
            return result;
        }
        
        var res2 =  createFunctions2();
        console.log(res2[0]());  // 0 
        console.log(res2[1]());  // 1

原則:
無名関数を定義し、無名関数の即時実行の結果を配列に代入します。ここの匿名関数にはパラメータ num があり、これは最終関数によって返される値です。各匿名関数を呼び出すときは、変数 i を渡します。関数のパラメータは値によって渡されるため、変数 i の現在の値がパラメータ num にコピーされます。この無名関数内で、num にアクセスするクロージャが作成され、返されます。このように、結果配列内の各関数は num 変数の独自のコピーを持つため、異なる値を返すことができます。

(2) 匿名関数がクロージャ関数の外側に含まれる場合、これはグローバル

        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function () {   
                return function () {        //匿名函数执行具有全局性
                    return this.name;       //this指向window
                };
            }
        };

        console.log(object.getNameFunc()())  //  The Window

Principle:
各関数が呼び出されるときに 2 つの特殊変数を自動的に取得します。 : これと引数。内部関数

がこれら 2 つの変数を検索する場合、アクティブなオブジェクトまでしか検索されないため、この時点では getNameFunc() は匿名関数を返します。したがって、この匿名関数はグローバルです。グローバル ウィンドウを指します

解決策:

このオブジェクトをクロージャがアクセスできる変数の外部スコープに保存し、クロージャがオブジェクトにアクセスできるようにします

    var name2 =  "The  Window";
    var object2 = {
        name:"My Object",
        getNameFunc:function(){
            var that =  this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中)
            return function (){
                return that.name
            }
        }
    }
    
    console.log(object2.getNameFunc()())   //My Object

(3)

クロージャの欠点
(1)。クロージャはそれを含む関数のスコープを保持するため、他の関数よりも多くのメモリを占有します。クロージャを過度に使用すると、過剰なメモリ使用量が発生する可能性があります

(2)。クロージャは関数内の変数の最後の値しか取得できないため、



列の記述に注意してください。






                                                                                                    

姧路                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           3分前に投稿 7回読む                                                             読むのに12分かかります                                           JavaScript クロージャー関数の基本的な使用法と発生した問題の解決策

#                                                                                 
                                                                                                                                                                                                                                                                                                                                                                                     
  • #面接中、クロージャとは何かといつも聞かれました。これまでは、要約するどころか、あまり気にしていませんでした。

クロージャ

は、他の関数の内部変数
を読み取ることができる関数です。

つまり、本質的に、クロージャは関数の内部と関数の外部を接続する橋です。

(1) クロージャの最も基本的なアプリケーション:

少废话,上代码

还是<<javascript高级程序设计>>的栗子,
function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];

        if(value1 < value2) {
            return -1;
        } else if(value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    };
}
var compare = createComparisonFunction("name"); 

var result = compare({ name: "Nicholas" }, { name: "Greg" });

分析:
(1) クロージャ関数はその外部関数にアクセスできます
返される匿名関数はクロージャ関数であり、アクティブです。外部関数にアクセスするこの匿名関数のオブジェクトは、propertyName パラメーターです。外部スコープ チェーンはこの匿名関数に含まれているため (比較関数には
createComparisonFunction() 関数のアクティブ オブジェクトとグローバル変数オブジェクトが含まれているとも解釈できます)、返された匿名関数は常にその外部にアクセスできます。 propertyName とグローバル変数。
(2) クロージャによって参照される外部変数は、その変数が配置されているスコープの破棄によって破棄されません。
外部関数のアクティブなオブジェクトは、返されたクロージャ関数内で参照されるため、 createComparisonFunction() のアクティブ オブジェクト (つまり propertyName) は、createComparisonFunction() の実行後に破棄されません。 createComparisonFunction は実行後に実行環境内のスコープ チェーンを破棄しますが、そのアクティブ オブジェクトは依然としてクロージャ関数によって参照され、匿名関数


# (2) の実行環境のスコープに配置されるためです。クロージャの副作用

(1)。クロージャは関数内の変数の最後の値しか取得できません。

        function createFunctions(){ 
            var result = new Array(); 
            for (var i=0; i < 10; i++){ 
                result[i] = function(){ 
                return i; 
                }; 
            } 
            return result; 
        }
        
        var res = createFunctions();
        console.log(res[0]());  //10
        console.log(res[1]());  //10
原理:

各関数は createFunctions() のアクティブなオブジェクトであるためです。関数はスコープ チェーンに格納されるため、すべて同じ変数 i を参照します。 createFunctions() 関数が戻ると、変数 i の値は 10 になります。このとき、各関数は変数 i を保存する同じ変数オブジェクトを参照するため、各関数内の i の値は 10

になります。 :

获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
        function  createFunctions2(){
            var result  = new Array();
            for(var i = 0 ; i <10 ; i++){
                result[i] = (function(num){
                    return function(){
                        return num
                    }
                })(i)
            }
            return result;
        }
        
        var res2 =  createFunctions2();
        console.log(res2[0]());  // 0 
        console.log(res2[1]());  // 1
原則:

無名関数を定義し、無名関数の即時実行の結果を配列に代入します。ここの匿名関数にはパラメータ num があり、これは最終関数によって返される値です。各匿名関数を呼び出すときは、変数 i を渡します。関数のパラメータは値によって渡されるため、変数 i の現在の値がパラメータ num にコピーされます。この無名関数内で、num にアクセスするクロージャが作成され、返されます。このように、結果配列内の各関数は num 変数の独自のコピーを持つため、異なる値を返すことができます。

(2) 匿名関数がクロージャ関数の外側に含まれる場合、これはグローバル

        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function () {   
                return function () {        //匿名函数执行具有全局性
                    return this.name;       //this指向window
                };
            }
        };

        console.log(object.getNameFunc()())  //  The Window
Principle:

各関数が呼び出されるときに 2 つの特殊変数を自動的に取得します。 : これと引数。内部関数
がこれら 2 つの変数を検索する場合、アクティブなオブジェクトまでしか検索されないため、この時点では getNameFunc() は匿名関数を返します。したがって、この匿名関数はグローバルです。グローバル ウィンドウを指します

解決策:

このオブジェクトをクロージャがアクセスできる変数の外部スコープに保存し、クロージャがオブジェクトにアクセスできるようにします

    var name2 =  "The  Window";
    var object2 = {
        name:"My Object",
        getNameFunc:function(){
            var that =  this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中)
            return function (){
                return that.name
            }
        }
    }
    
    console.log(object2.getNameFunc()())   //My Object

(3)

クロージャの欠点
(1)。クロージャはそれを含む関数のスコープを保持するため、他の関数よりも多くのメモリを占有します。クロージャを過度に使用すると、過剰なメモリ使用量が発生する可能性があります
(2)。クロージャは関数内の変数の最後の値しか取得できないため、


# の記述に注意してください。 ############################################報告#####

  • JavaScript クロージャー関数の基本的な使用法と発生した問題の解決策



## ####コメント###                                                                                            時間順に並べ替え


読み込み中...

コメントをさらに表示

## #############################

以上がJavaScript クロージャー関数の基本的な使用法と発生した問題の解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。