の違いについて教えてください"を使う"、"var"?
-
11-09-2019 - |
質問
ECMAScript6に導入 の let
決.
聞いたのですが、これらの記述としての"地方"の変数がまだないように動作しなの var
キーワードとなります。
何が違っていたのか?べきであ let
定することが var
?
解決
スコープの規則
主な違いは、ルールをスコープです。 var
変数はlet
(従って、ブロック範囲)で表さ即時封入のブロックにスコープされている間{ }
キーワードで宣言された変数は、即時関数本体(したがって関数スコープ)にスコープされます。
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar);
{
let baz = "Bazz";
console.log(baz);
}
console.log(baz); // ReferenceError
}
run();
let
キーワードが言語に導入された理由は、関数スコープが混乱していたとJavaScriptのバグの主な情報源の一つであった。
他のヒント
let
も閉鎖に伴う問題を回避するために使用することができます。それは以下の例に示すように、古い参照を維持するのではなく、新鮮な値をバインドします。
for(var i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
上記のコードは、古典的なJavaScriptの閉鎖問題を示します。 i
変数への参照ではなくi
の実際の値よりも、クリックハンドラの閉鎖に格納されてます。
6そう、あなたがクリックするたびに6を取得し保持している唯一のカウンターオブジェクトがありますので、ひとつひとつのクリックハンドラは、同じオブジェクトを参照します。
一般的な問題を回避するには、匿名関数でこれをラップし、引数としてi
を渡すことです。このような問題はまた、以下のコードに示すようにlet
代わりvar
用いて今回避することができる。
<サブ>(クロームとFirefox 50でテスト済み)サブ>
for(let i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
の違いについて教えてください let
や var
?
理解の違いは、以下のコード:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
ており、今も多くの人が訪れている当社の可変 j
が知られていて初めてループがないに関する分析を行っている。しかし、当社の可変 i
が知られている全体の機能です。
また、このブロックscoped変数まで知らなかで宣言されていないので吊り上げ.まもなredeclare同じブロックscoped変数のブロックです。このブロックscoped変数に誤差がより世界的には機能的にscoped変数は、吊り上げ、発生しないエラーの場合複数の宣言も行いました。
で安全に使用 let
ます。
一部の人々と主張するだろうと述べ、今後までのみ利用しよう明るvar諸表となり互換性のために残されています。JavaScriptのグル カシンプソン 書 非常に精巧な記事かと考えている場合.
しかし、今日はありません。もし実際に、私たちはるかどうかで安全な利用の let
ます。その答えは環境により異なり:
い書サーバサイドJavaScriptコードNode.js)まで、安心して利用
let
ます。だが筆記のclient-side JavaScriptコードを使いのブラウザベー transpiler( Traceur または バベル-ロ)まで、安心して利用
let
決しかしながら、お客様のコードが可能な最適なる。だが筆記のclient-side JavaScriptコード、ノードを使に基づくtranspiler( traceurシェルスクリプト または バベル)まで、安心して利用
let
ます。だからブラウザのみについて知transpiledコード、パフォーマンスの欠点を広げることができればすばだが筆記のclient-side JavaScriptコードな使用transpilerを考える必要がありブラウザです。
まだまだ一部のブラウザをサポートしない
let
:
どのブラウザを支援
ための最新の概要をブラウザを支援 let
算時に読みこの答えは、 この Can I Use
ページ.
* 世界的にも機能的scoped変数を初期化することができ、使用の前に宣言されていなJavaScriptの変数 吊り上げ. この宣言は常に、トップを務める。
** ブロックscoped変数は吊り上げ
受け入れ答えは、ポイントが不足しています:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
let
ブロック範囲
宣言した変数の使用 let
キーワードはブロック-scopedすることがでのみご利用いただけ ブロック とした宣言しています。
トップレベル外の機能)
トップレベルに宣言した変数の使用 let
な創造性、グローバルオブジェクトです。
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
内部機能
内部機能は外部のブロック), let
同じ範囲として var
.
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
内部ブロック
宣言した変数の使用 let
内部ブロックできないアクセス以外のブロックです。
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
内部ループ
変数宣言 let
でループも参照が可能ですので内部のみにこのループを実行します。
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
ループとの閉鎖
ご利用の場合 let
の代わりに var
ループでは、各反復する新しい可変となります。ることをすることになりますので安全に利用できるクロージャ内のループを実行します。
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
時間的不感帯
での 時間的不感帯, 変数の宣言 let
なアクセスされる前に宣言しています。ようというスローエラーとなります。
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
なの再宣言
できませんを宣言するのと同じ変数を複数回使用 let
.することができません宣言変数の使用 let
同じ識別子としてく変動したために使用され var
.
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
const
const
とよく似た let
でブロック-scoped、TDZ.が、しかし、二つのものが異なります。
な再割り当
宣言した変数の使用 const
できませんの再割り当てられます。
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
りますのでご注意えてくるということではないの価値は変更できません。その性質も変更できます。
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
したい場合において不変のオブジェクトを使用してみてください Object.freeze()
.
初期化が必要
まずを指定しなければな価値を宣言する場合、変数を使用 const
.
const a; // SyntaxError: Missing initializer in const declaration
ここでは、2つの(ちょうどクロムのために始まっサポート)との差のための例です。
はvar j
変数が依然としてループスコープの(ブロックスコープ)外の値を有しているが、let i
変数がループスコープのための外部定義されていない。見ることができるように
"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
console.log(j);
}
console.log(j);
console.log("let:");
for (let i = 0; i < 2; i++) {
console.log(i);
}
console.log(i);
いくつかの微妙な違いがあります - let
スコープは、より多くの変数のスコープのように振る舞い、多かれ少なかれ、他の言語ではありません。
例えば。それは彼らが、宣言されている前に、彼らが存在しない、外側のブロックにスコープなど。
しかし、それはlet
は新しいJavaScriptの実装の一部に過ぎないとブラウザのサポートの度合いを変化させたことは注目に値します>。
変数のない巻上let
ま ないブロック の範囲のブロックに表示されます。逆に、var
がブロックしています。{ console.log(cc); // undefined. Caused by hoisting var cc = 23; } { console.log(bb); // ReferenceError: bb is not defined let bb = 23; }
実際には、@Bergi, 両
var
やlet
は吊り上げ.ゴミの収集
ブロックの範囲
let
有するクロージャやゴミを取り戻す。の検討,function process(data) { //... } var hugeData = { .. }; process(hugeData); var btn = document.getElementById("mybutton"); btn.addEventListener( "click", function click(evt){ //.... });
の
click
ハンドラコールバックの必要もありませんhugeData
変数です。理論的には、process(..)
走る、巨大なデータ構造hugeData
このゴミを収集します。しかし、まれてくる可能性があることであJSエンジンもしこのように構成すれば、click
機能閉鎖全体に渡る。しかし、ブロック範囲ではこの膨大なデータ構造のゴミを収集します。
function process(data) { //... } { // anything declared inside this block can be garbage collected let hugeData = { .. }; process(hugeData); } var btn = document.getElementById("mybutton"); btn.addEventListener( "click", function click(evt){ //.... });
let
ループlet
ループで 再結合するので 各繰り返し処理のループ構成されている再割り当ての値から前のループになります。の検討,// print '5' 5 times for (var i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); }, 1000); }
ただし、置き換え
var
とlet
// print 1, 2, 3, 4, 5. now for (let i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); }, 1000); }
ので
let
新しい語彙かな環境でのこれらの名称をinitialiser表現はそれ以上の繰り返し処理(previoslyの評価の増分式が、詳細は こちらの.
主な違いは、 範囲 差が ましょう できるだけご利用中の 範囲 この宣言されたように、ループ var アクセスできるのは外側のループです。からの文書に MDN (例からもMDN):
ましょう できる変数を宣言するのに制限の対象範囲をさらにブロック、または表現で使用します。これとは異なり、 var キーワードを定義する変数は世界的に、地域全体の機能に関わらずブロックです。
変数を宣言する ましょう としてその範囲のブロック内で定義され、いずれのサブブロックとなります。このように、 ましょう 作品のようなものだ var.主な違いは、範囲の var 変動の全体を包接機能:
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}`
トップレベルのプログラムと機能 ましょう, とは異なり、 var, ませんのプロパティを作成しますのオブジェクトです。例えば:
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
で使われた場合、ブロックのみを制限する変数の範囲にそのブロックです。の違いに注意してくださ var その範囲内での機能で宣言しています。
var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2
も忘れないでECMA6特徴なされないので、常に向上transpilesでECMA5用バベル。のための詳細情報訪問 バベルサイト
ここで他の人がすでに書かれているものにに追加する例を示します。あなたは、各機能は、単一の数値引数を取り、配列内の引数の合計と関数のインデックスを返す関数の配列、adderFunctions
を作りたいとします。誰かが単純に期待するかもしれないように動作しませんadderFunctions
キーワードを使用してループを備えたvar
を生成しようとしてます:
// An array of adder functions.
var adderFunctions = [];
for (var i = 0; i < 1000; i++) {
// We want the function at index i to add the index to its argument.
adderFunctions[i] = function(x) {
// What is i bound to here?
return x + i;
};
}
var add12 = adderFunctions[12];
// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000
// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true
i
の範囲は、各関数が作成されたfor
ブロックの繰り返しを越えて延びているので、上記のプロセスは、機能の所望の配列を生成しません。代わりに、ループの終了時に、各機能の閉鎖にi
はi
内のすべての匿名関数のループ(1000)の端部にadderFunctions
の値を指します。これは、我々は全く望んでいたものではありません。私たちは今、まったく同じ動作でメモリに1000の異なる関数の配列を持っています。私たちは、その後i
の値を更新した場合や、変異はすべてadderFunctions
に影響します。
しかし、我々はlet
キーワードを使用して再度試すことができます:
// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];
for (let i = 0; i < 1000; i++) {
// NOTE: We're using the newer arrow function syntax this time, but
// using the "function(x) { ..." syntax from the previous example
// here would not change the behavior shown.
adderFunctions[i] = x => x + i;
}
const add12 = adderFunctions[12];
// Yay! The behavior is as expected.
console.log(add12(8) === 20); // => true
// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined
この時間は、i
はfor
ループの各反復でリバウンドです。各関数は、現在の関数の作成時にi
の値を保持し、かつadderFunctions
が期待通りに動作します。
さて、画像は2つの動作を混合し、同じスクリプトで古いlet
と新しいconst
とvar
を混在しないことをお勧めしている理由は、おそらく表示されます。そうすることで、いくつかの見事に混乱のコードで発生することができます。
const doubleAdderFunctions = [];
for (var i = 0; i < 1000; i++) {
const j = i;
doubleAdderFunctions[i] = x => x + i + j;
}
const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];
// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
これはあなたに起こるせてはいけません。リンターを使用します。
注:これは、ループにしても理解しやすいだろう機能の閉鎖と
var
/let
の動作を実証することを目的と指導例です。これは、数字を追加する恐ろしい方法だろう。しかし、匿名関数クロージャ内のデータを取り込むの一般的な手法は、他のコンテキストで現実の世界で遭遇するかもしれません。 YMMVます。
その違いは、 範囲 変数の宣言されています。
実際、数多くの便利な結果の違い範囲:
let
変数のみに見えるその 最寄り囲む ブロック{ ... }
).let
変数のみに使用できるラインのコードで発生する 後 変数は宣言されたものと その吊り上げ!).let
変数はredeclaredによるその後のvar
またはlet
.- グローバル
let
変数を付加していないグローバルwindow
オブジェクトです。 let
変数 使いやすい と閉鎖(れんを起こさない レースの条件).
の制約の let
削減の視認性の変数の増加の可能性が想定外の名前の衝突が見つかります。それによるトラックとした理由変数を含む 到達可能性(人再生未使用いたしました。
その結果、 let
変数が起こると考えられている問題が大きなプログラムが独自に開発した枠組みに組み合わせて新しい。
var
がなければならないときに便利で使いたい単結合の効果をお使いの場合閉ループ(#5)または宣言する外-可視のグローバル変数コード(#4).の利用 var
輸出するsupplanted場合 export
に移動のtranspiler空間の言語です。
例
1.利用以外の最寄り囲むブロック:
このブロックのコードをスローします参照エラーでの使用 x
が外部のブロックで宣言されて let
:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
一方、同一例 var
ます。
2.利用の前に宣言:
このブロックをコードする ReferenceError
前のコードが実行されるので x
使用の前で宣言された:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
一方、同一例 var
を解析しとせずに投げ入れることができます。
3.なredeclaration:
次のコードをみると、この変数の宣言 let
なredeclared降:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4.グローバル変数付属しません window
:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5.使いやすいとの閉鎖:
変数宣言 var
には対応していませんの閉鎖内のタイルです。ここにあるという単純なループの出力の値のシーケンスの変数 i
は異なる時点に:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
具体的には、この出力:
i is 0
i is 1
i is 2
i is 3
i is 4
JavaScriptを用いる事が多いの変数で大幅に遅時間が作成されます。きのこによる遅延の出力を閉鎖に渡される setTimeout
:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
...出力は依然として大きな変化はみられない、まっ let
.一方、いたとします。 var i
代わり:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
...ループの不意に出力"は5"五回:
i is 5
i is 5
i is 5
i is 5
i is 5
次の2つの関数は違いが表示されることがあります:
function varTest() {
var x = 31;
if (true) {
var x = 71; // Same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // Different variable
console.log(x); // 71
}
console.log(x); // 31
}
let
は、興味深いものです。
(() => {
var count = 0;
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
カウントをもたらす[0,7]。
一方、
(() => {
var count = 0;
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
のみ[0、1]をカウントします。
機能VSブロック範囲:
主な違い var
や let
この変数の宣言されて var
は 機能scoped.は機能が宣言されて let
は ブロックscoped.例えば:
function testVar () {
if(true) {
var foo = 'foo';
}
console.log(foo);
}
testVar();
// logs 'foo'
function testLet () {
if(true) {
let bar = 'bar';
}
console.log(bar);
}
testLet();
// reference error
// bar is scoped to the block of the if statement
変数 var
:
最初の機能 testVar
が呼び出され、変数foo,宣言されて var
, では、まだアクセス以外の if
ます。この変数 foo
利用できることと 随所に の範囲内での testVar
機能.
変数 let
:
第二次機能 testLet
が呼び出され、変数バー宣言 let
, は、アクセスの if
ます。で変数の宣言されて let
は ブロックscoped (aブロックは、コードの間に巻きブラケットe.g if{}
, for{}
, function{}
).
let
変数んの吊上げ:
もう一つの違いと var
や let
は変数の宣言 let
な吊り上げ.例の最善の方法でこれを説明するために行動
変数 let
な 車吊り上げ:
console.log(letVar);
let letVar = 10;
// referenceError, the variable doesn't get hoisted
変数 var
い 車吊り上げ:
console.log(varVar);
var varVar = 10;
// logs undefined, the variable gets hoisted
グローバル let
ん付 window
:
変数宣言 let
のグローバルなスコープ(コードにない機能がないとして追加プロパティのグローバル window
オブジェクトです。例えばこのコードはグローバル範囲):
var bar = 5;
let foo = 10;
console.log(bar); // logs 5
console.log(foo); // logs 10
console.log(window.bar);
// logs 5, variable added to window object
console.log(window.foo);
// logs undefined, variable not added to window object
べきであ
let
定することがvar
?
使用 let
以上 var
りできるのではなscopedます。このよ命名紛争が取り扱う場合には大量の変数. var
できる場合に用いるグローバル変数を明示的にすること window
オブジェクトは常に注意深く考える場合には本当に必要です。
また、少なくとものVisual Studio 2015、活字体1.5で、「varが」ブロックで同じ変数名の複数の宣言を可能にし、「せ」ない、と思わます。
これは、コンパイルエラーを生成しません。
var x = 1;
var x = 2;
この意志ます:
let x = 1;
let x = 2;
var
は、グローバルスコープ(ホイスト可能な)変数である。
let
とconst
スコープブロックである。
test.js
{
let l = 'let';
const c = 'const';
var v = 'var';
v2 = 'var 2';
}
console.log(v, this.v);
console.log(v2, this.v2);
console.log(l); // ReferenceError: l is not defined
console.log(c); // ReferenceError: c is not defined
利用の場合 let
の let
キーワード付きの変数の宣言の範囲のあらゆるものをブロックを入れ { .. }
ペア)が含まれる。つまり、let
暗黙のうちにhijacks他のブロックの範囲、その変数宣言です。
let
変数にアクセスできないの window
オブジェクトがないため世界的にご利用いただけます。
function a(){
{ // this is the Max Scope for let variable
let x = 12;
}
console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined
利用の場合 var
var
や変数ES5はスコープ機能的に意味の変数が有効に機能しない外部の機能そのものです。
var
変数にアクセスできるので、 window
オブジェクトがないため世界的にご利用いただけます。
function a(){ // this is the Max Scope for var variable
{
var x = 12;
}
console.log(x);
}
a(); // 12
ばもっと知りたい続きを読む下
最も有名なる質問への対応範囲で十分に正確な使用 let
や var
下記のよ
利用の場合 let
for (let i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 0 to 9, that is literally AWW!!!
},
100 * i);
}
これは利用の場合 let
, 毎ループの繰り返し、変数scopedを自動的にコピーします。
利用の場合 var
for (var i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 10 times 10
},
100 * i);
}
これは利用の場合 var
, 毎ループの繰り返し、変数scopedと共にコピーします。
私は仕様を読めば右クリックlet
のありがたいのも<のhref = "https://stackoverflow.com/questions/592396/what-is-the-purpose-を回避するために活用することができます#592414" 自己実行機能・イン・javascriptの-のプライベートメンバーのみをシミュレートするために使用する>自己呼び出す機能 - コードの可読性を低下させ、の人気のデザインパターン、デバッグを複雑にし、本当を追加していないことコード保護または他の利点は - 多分セマンティクスのために誰かの欲求を満たす除いて、それを使用して停止します。 /暴言の
var SomeConstructor;
{
let privateScope = {};
SomeConstructor = function SomeConstructor () {
this.someProperty = "foo";
privateScope.hiddenProperty = "bar";
}
SomeConstructor.prototype.showPublic = function () {
console.log(this.someProperty); // foo
}
SomeConstructor.prototype.showPrivate = function () {
console.log(privateScope.hiddenProperty); // bar
}
}
var myInstance = new SomeConstructor();
myInstance.showPublic();
myInstance.showPrivate();
console.log(privateScope.hiddenProperty); // error
let
といくつかのハッキングます:
1。
let statistics = [16, 170, 10];
let [age, height, grade] = statistics;
console.log(height)
2。
let x = 120,
y = 12;
[x, y] = [y, x];
console.log(`x: ${x} y: ${y}`);
3。
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
let node = {
type: "Identifier"
};
let { type: localType, name: localName = "bar" } = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"
ゲッターとlet
とセッター:
let jar = {
numberOfCookies: 10,
get cookies() {
return this.numberOfCookies;
},
set cookies(value) {
this.numberOfCookies = value;
}
};
console.log(jar.cookies)
jar.cookies = 7;
console.log(jar.cookies)
しようvs var.すべて 範囲.
var変数はグローバル アクセスできるのでは基本的にあふれ、 う変数はグローバル にのみ存在しま載殺しました。
マ例を以下に注意してどのようにライオン(let)可変する行為なのです。丸太;となりの範囲第2回ソフトである。ログです。
var cat = "cat";
let dog = "dog";
var animals = () => {
var giraffe = "giraffe";
let lion = "lion";
console.log(cat); //will print 'cat'.
console.log(dog); //will print 'dog', because dog was declared outside this function (like var cat).
console.log(giraffe); //will print 'giraffe'.
console.log(lion); //will print 'lion', as lion is within scope.
}
console.log(giraffe); //will print 'giraffe', as giraffe is a global variable (var).
console.log(lion); //will print UNDEFINED, as lion is a 'let' variable and is now out of scope.
letがES6の一部です。これらの機能は、簡単な方法で違いを説明します。
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
以前すなわち機能とグローバルJavaScriptで唯一2つのスコープがありました。 'let
' キーワードでJavaScriptが今block-level
変数を導入しています。
の<のhref = "http://www.codingeek.com/tutorials/javascript/es6-let-keyword-to-declare-variable-in、 '聞かせて' キーワードを完全に理解しているために、 -javascript /」のrel = "nofollowをnoreferrer"> ES6:キーワードが役立つのJavaScript のの中で変数を宣言するために「聞かせて」
。今、私はlet
を使用してステートメントのブロックへの変数のより良いスコープがあると思います:
function printnums()
{
// i is not accessible here
for(let i = 0; i <10; i+=)
{
console.log(i);
}
// i is not accessible here
// j is accessible here
for(var j = 0; j <10; j++)
{
console.log(j);
}
// j is accessible here
}
私は人々が、彼らはなど他の言語のようなJavaScriptで同様のスコーピング、ジャワ、C#を、持っていることの後に、ここで聞かせて使用を開始すると思います。
JavaScriptでスコープについての明確な理解ではないと人々は、以前の過ちを作るために使用される。
を巻き上げはlet
を使用してサポートされていません。
はJavaScriptに存在するこのアプローチのエラーでは削除得ています。
この記事では明らかにVARの違いを定義し、聞かせてとのconst
const
識別子が再割り当てされないことを信号である。あなたは、変数を定義するときに
let
、変数のような、再割り当てされてもよいという信号であります ループカウンタ、またはアルゴリズムの値スワップ。また、信号 変数は唯一それがで定義されていますブロックで使用されることを、 これは、常に関数を含む全体ではありません。
var
が利用可能になりまし最も弱い信号であり、 JavaScriptをインチ変数がよく、または再割り当てすることはできませんし、 変数は、全体の機能のために、または単にのために使用してもしなくてもよいです ブロックまたはループの目的
ます。https://メディア。 COM / javascriptのシーン/ javascriptの-ES6-VAR-レットまたはconstで-ba58b8dcde75#.esmkpbg9bする
上記:
その違いはスコーピング.
var
はscoped最寄りの 機能 ブロック やlet
はscopedの 最寄り囲むブロック, は、 で活用することで、低コストで高機能ブロックです。もグローバルの場合外 ブロックです。可能です。:
Example1:
私の両方の事例が機能 myfunc
. myfunc
可変 myvar
equals10人になりました。初めての例では認した場合 myvar
equals10(myvar==10
).そして、agian変数を宣言する myvar
(現していmyvar変数の使用 var
キーワードを割り当てで新しい価値(20).に次の行を印刷し、その価値を自分です。後の条件付きブロックし再度の値を印刷 myvar
私のソフトである。また、出力の myfunc
, myvar
価値=20.
Example2:
私の第二の例を使用 var
キーワード私の条件付きブロックることをここに宣言します myvar
を使用 let
キーワードとなります。今話 myfunc
かの異なる二つの出力: myvar=20
や myvar=10
.
その差は非常に簡単ないeした。
私は条件を考えると、例のほとんどは少し圧倒され、
私は違いを個人的に持っていた主な問題は、「ブロック」とは何であるか理解することです。
私が実現し、いくつかの時点で、ブロックはIF
声明を除く任意の波括弧だろう。
機能またはループの開口ブラケット{
新しいブロックを定義し、その中let
で定義されたものは、同じものの閉鎖ブラケット}
(機能またはループ)の後に使用できません。
このことを念頭に置いて、理解することが簡単だった。
let msg = "Hello World";
function doWork() { // msg will be available since it was defined above this opening bracket!
let friends = 0;
console.log(msg);
// with VAR though:
for (var iCount2 = 0; iCount2 < 5; iCount2++) {} // iCount2 will be available after this closing bracket!
console.log(iCount2);
for (let iCount1 = 0; iCount1 < 5; iCount1++) {} // iCount1 will not be available behind this closing bracket, it will return undefined
console.log(iCount1);
} // friends will no be available after this closing bracket!
doWork();
console.log(friends);
していることができるよう詳細な理解のJavaScriptに渡っ簡単なる研究の一部が含まれての個みによってプラスその他の詳細は異なる視点です。
理解の違い var や ましょう できやすい違いをわかりやすくする 機能 や ブロック範囲.
るのかを考えてみましょう、以下の場合:
(function timer() {
for(var i = 0; i <= 5; i++) {
setTimeout(function notime() { console.log(i); }, i * 1000);
}
})();
Stack VariableEnvironment //one VariablEnvironment for timer();
// when the timer is out - the value will be the same value for each call
5. [setTimeout, i] [i=5]
4. [setTimeout, i]
3. [setTimeout, i]
2. [setTimeout, i]
1. [setTimeout, i]
0. [setTimeout, i]
####################
(function timer() {
for (let i = 0; i <= 5; i++) {
setTimeout(function notime() { console.log(i); }, i * 1000);
}
})();
Stack LexicalEnvironment - each iteration has a new lexical environment
5. [setTimeout, i] [i=5]
LexicalEnvironment
4. [setTimeout, i] [i=4]
LexicalEnvironment
3. [setTimeout, i] [i=3]
LexicalEnvironment
2. [setTimeout, i] [i=2]
LexicalEnvironment
1. [setTimeout, i] [i=1]
LexicalEnvironment
0. [setTimeout, i] [i=0]
時 timer()
が呼び出される ExecutionContext 作成することができますの VariableEnvironment すべての LexicalEnvironments 各なります。
と簡単な例
機能範囲
function test() {
for(var z = 0; z < 69; z++) {
//todo
}
//z is visible outside the loop
}
ブロック範囲
function test() {
for(let z = 0; z < 69; z++) {
//todo
}
//z is not defined :(
}
私は、実行コンテキストは、このすべてで重要であるため、実行コンテキストにこれらのキーワードをリンクしたいです。作成フェーズと実行フェーズ:実行コンテキストは、2つの段階があります。また、各実行コンテキストは変数環境と外部環境(その語彙環境)を有しています。
実行コンテキストの作成段階では、VAR、聞かせてとのconstはまだ特定の実行コンテキストの変数環境に未定義値をメモリ内の変数を格納します。違いは、実行フェーズです。あなたはそれが値を割り当てられる前にVARで定義された変数を参照を使用している場合は、それだけ不定となります。例外は発生しません。
それが宣言されるまで、ただし、LETかのconstで宣言された変数を参照することはできません。あなたはそれが宣言される前にそれを使用しようとすると、例外は実行コンテキストの実行フェーズ中に発生します。今、変数はまだ、メモリ内の実行コンテキストの作成段階の礼儀になりますが、エンジンは、あなたがそれを使用することはできません。
function a(){
b;
let b;
}
a();
> Uncaught ReferenceError: b is not defined
エンジンは、現在の実行コンテキストの変数の環境で変数を見つけることができない場合はVARで定義された変数で、それはスコープチェーン(外部環境)を上がると、変数のための外部環境の変数の環境を確認してください。それはそこにそれを見つけることができない場合は、スコープチェーンを探し続けます。これは、LETとconstの場合ではありません。
letの第二の特徴は、それがブロックスコープを導入しています。ブロックは中括弧で定義されています。例としては、ブロックは、ブロックなどのためにあなたがブロックの内側にletで変数を宣言する場合ならば、変数はブロックの内側にのみ使用可能です、機能ブロックを含みます。実際には、ブロックは、このようなforループ内など、実行されるたびに、それは、メモリ内に新しい変数を作成します。
ES6も、変数を宣言するためのconstキーワードを紹介します。 constがまた、スコープのブロックです。 LETとのconstの違いは、constの変数が初期化子を使用して宣言する必要がある、またはそれがエラーを生成するということです。
それが実行コンテキストに来るとき、そして、最後に、VARで定義された変数「はこの」オブジェクトに添付されます。グローバル実行コンテキストでは、それはブラウザでウィンドウオブジェクトになります。これはLETまたはconstのためのケースではありません。