ホームページ ウェブフロントエンド jsチュートリアル JS Core シリーズ: 関数の範囲に関する簡単な説明

JS Core シリーズ: 関数の範囲に関する簡単な説明

Jan 24, 2017 am 11:34 AM
js 範囲 関数

1. スコープ

いわゆるスコープは、変数が宣言されている関数本体と、この関数本体がネストされている関数本体で定義されます。

function scope(){
    var foo = "global";
    if(window.getComputedStyle){
        var a = "I'm if";
        console.log("if:"+foo); //if:global
    }
    while(1){
        var b = "I'm while";
        console.log("while:"+foo);//while:global
        break;
    }
    !function (){
        var c = "I'm function";
        console.log("function:"+foo);//function:global
    }();
    console.log(
         foo,//global
         a, // I'm if
         b, // I'm while
         c  // c is not defined
    );
}
scope();
ログイン後にコピー

(1)scope 関数で定義された foo 変数は、それ自体でアクセスできるだけでなく、if ステートメント、while ステートメント、および埋め込まれた匿名関数からもアクセスできます。 したがって、foo のスコープはスコープ関数本体になります。

(2) JavaScript では、if、while、for などのコード ブロックは独立したスコープを形成できません。したがって、JavaScript にはブロックレベルのスコープはなく、関数スコープのみが存在します。

ただし、JS には特殊なケースがあります:

変数が var で宣言されていない場合、ウィンドウはこの属性を持つことになるため、この変数のスコープは特定の関数本体に属さず、ウィンドウオブジェクト。

function varscope(){
    foo = "I'm in function";
    console.log(foo);//I'm in function
}
varscope();
console.log(window.foo); //I'm in function
ログイン後にコピー

2. スコープ チェーン

いわゆるスコープ チェーンとは、関数本体の複数の層がネストされており、同じ変数が異なる関数本体で定義されているものです。関数の一部がこの変数にアクセスすると、スコープ チェーンが形成されます。

foo = "window";
function first(){
    var foo = "first";
    function second(){
       var foo = "second";
       console.log(foo);
    }
    function third(){
       console.log(foo);
    }
    second(); //second
    third();  //first
}
first();
ログイン後にコピー

ond の場合、JS エンジンはリンク リストの先頭に Second のスコープを配置し、続いて First のスコープ、最後に window オブジェクトを配置します。そのため、次のスコープ チェーンが形成されます:

Second-> ;first-> ウィンドウでは、この時点で、JS エンジンはスコープ チェーンに沿って変数 foo を検索し、「2 番目」を見つけます

3 番目が実行されると、3 番目によって形成されるスコープ チェーンは次のようになります: third->first- >ウィンドウなので、検索 私が得たものは次のとおりです: "frist"

特殊なケース: with ステートメント

JS の with ステートメントは、主にスコープ チェーンを一時的に拡張し、ステートメント内のオブジェクトを先頭に追加するために使用されます。範囲の。 with ステートメントが終了すると、スコープ チェーンは通常の状態に戻ります。

foo = "window";
function first(){
    var foo = "first";
    function second(){
       var foo = "second";
       console.log(foo);
    }
    function third(obj){
       console.log(foo); //first
       with (obj){
           console.log(foo); //obj
       }
       console.log(foo); //first
    }
    var obj = {foo:'obj'};
    third(obj);
}
first();
ログイン後にコピー

third() を実行すると、obj オブジェクトが渡され、obj には属性 foo が付けられます。with ステートメントを実行すると、JS エンジンは元のリンク リストの先頭に obj を配置し、形成されるスコープ チェーンは次のようになります。 :

obj->third->first->window、この時点で見つかった foo は obj の foo であるため、出力は次のようになります: "obj"、with の前後は、元のリンクに沿っていますlist with ステートメントの終了後にスコープ チェーンが通常に戻ったことを示すために検索が実行されます。

3. このキーワード

関数では、thisは常に現在の関数のオーナーオブジェクトを指します。this

は実行時にのみその特定のポインターを決定でき、その後でのみ決定できます私たちはその呼び出しオブジェクトを知っています。

この文はこれについてすべてを要約しています、覚えておいてください、覚えておいてください! (追記: 重要なことは 3 回言います!)

window.name = "window";
function f(){
    console.log(this.name);
}
f();//window

var obj = {name:'obj'};
f.call(obj); //obj
ログイン後にコピー

f() を実行するとき、この時点では f() 呼び出し元はウィンドウですオブジェクトなので、出力「window」

f.call(obj) は、obj オブジェクトに f() を配置して実行することになります。これは、obj.f() と同等です。このとき、f の this は obj、出力は "obj" です IV. 実用的なアプリケーション

code1:

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function(){
        return function(){
            return this.foo;
        };
    }
};
var f = obj.getFoo();
f(); //window
ログイン後にコピー

code2:

var foo = "window";
var obj = {
    foo : "obj",
    getFoo : function(){
        var that = this;
        return function(){
            return that.foo;
        };
    }
};
var f = obj.getFoo();
f(); //obj
ログイン後にコピー

code1 と code2 は、疑問がある場合に最適な要約です。実行結果については、ご相談ください。

コード分析:

code1:
执行var  f = obj.getFoo()返回的是一个匿名函数,相当于:
var f = function(){
     return this.foo;
}
f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window" 

code2:
执行var f = obj.getFoo() 同样返回匿名函数,即:
var f = function(){
     return that.foo;
}
唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回"obj"
ログイン後にコピー
🎜🎜
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C言語でのtypedef構造体の使い方 C言語でのtypedef構造体の使い方 May 09, 2024 am 10:15 AM

C言語でのtypedef構造体の使い方

Javaで期待される変数を解決する方法 Javaで期待される変数を解決する方法 May 07, 2024 am 02:48 AM

Javaで期待される変数を解決する方法

JSのクロージャーの長所と短所 JSのクロージャーの長所と短所 May 10, 2024 am 04:39 AM

JSのクロージャーの長所と短所

C++ で include は何を意味しますか C++ で include は何を意味しますか May 09, 2024 am 01:45 AM

C++ で include は何を意味しますか

C++ スマート ポインター: ライフサイクルの包括的な分析 C++ スマート ポインター: ライフサイクルの包括的な分析 May 09, 2024 am 11:06 AM

C++ スマート ポインター: ライフサイクルの包括的な分析

js の this が指す状況がいくつかあります。 js の this が指す状況がいくつかあります。 May 06, 2024 pm 02:03 PM

js の this が指す状況がいくつかあります。

Excel関数の公式の完全なコレクション Excel関数の公式の完全なコレクション May 07, 2024 pm 12:04 PM

Excel関数の公式の完全なコレクション

C++ での関数の定義と呼び出しはネストできますか? C++ での関数の定義と呼び出しはネストできますか? May 06, 2024 pm 06:36 PM

C++ での関数の定義と呼び出しはネストできますか?

See all articles