2016-06-20 4 views
1

は、このコードによると:直接new Thing持つかThing.create()と、次のいずれかなぜこの場合、内部関数は外部変数にアクセスできませんか?

class Thing { 
    constructor() { 
     this.bar = (typeof foo !== "undefined"? foo : null); // (3) 
    } 

    static create() { 
     var foo = arguments[0]; 
     return new Thing(); 
    } 
} 

新しいThingは、2つの方法で作成されることがあります。

2番目の方法で作成すると、新しい変数stringが宣言されます。理論的には、returnステートメントまでのすべてのスコープ内に表示する必要がありますが、Thing.constructor()Thing.create()と呼ばれます)ではstringは表示されません。 Thing.prototype.barは常にnullです。

なぜそうですか?ここ


それinner()関数から見ある:

(function outer() { 
    var foo = 5; 

    (function inner() { 
     alert(foo); 
    })() 
})(); 
理論

答えて

2

は、それがreturnステートメント

番までのすべての範囲内に表示されなければなりません

同じスコープ内で呼び出された関数では表示されません。私はどのような機能にも表示されますは同じ範囲内に作成されます。

この例では、constructor()関数は、string変数よりも高い範囲にあります。

これは動作します:

方法によって、ためにシンタックスシュガーに他ならない、
class Thing { 
    constructor(prop) { 
     this.prop = prop; 
    } 

    static create() { 
     return new Thing(arguments[0]); 
    } 
} 

:あなたはその関数から変数バインディングを継承(機能が起こることを期待している何

function Thing(prop) { 
    this.prop = prop; 
} 
Thing.create = function() { 
    return new Thing(arguments[0]); 
}; 
+1

'使用strict'モードのjavascriptの外側には、[VARの巻き上げ](と呼ばれる範囲のルックアップを実行しますhttps://developer.mozilla。おそらくOPが混乱しているかもしれませんが、closureとhoistingについて読むと、 'var foo'がコンストラクタ内に存在しない理由を説明してくれることを願っています。 'create()' – kirinthos

+0

あなたは完全に正しいと申し訳なく思っています。宣言せずに変数を使うことを考えていましたが、関数の変更については何も言わなかっただけです。これはコンストラクタでfooにアクセスできない理由を説明しています – kirinthos

+0

第2の例では、 'create 'はおそらく' Thing'のプロトタイプではなく 'function Thing'自体にアタッチされるべきです。私はこれが、静的関数が最も機能すると思う方法だと思います。 – noppa

2

それらを呼ぶ)は動的可変スコープとして知られています。一方、Javascriptはのstaticのlexicalとも呼ばれます)変数スコープを持ちます。これは、変数バインディングがソースコード内でどの関数がネストされているかにのみ基づいていることを意味します。これは良いことです。なぜなら、変数の意味を理解するために関数が呼び出される方法について考える必要がないからです。関数の記述方法を調べるだけです。

字句と動的スコープの違いの詳細について

、Wikipediaの記事を開始するには良い場所のようだ:https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping

関連する問題