Safari(11.1.1)@Sierra(10.12.6, final Sierra)のdev tool, consoleで確認
console.log(date) // Can't find variable: date
date = Date('2018-07-15');このdateは巻き上げが効かないだけで
var date = Date('2018-07-15');このdateと同じglobal変数だ。
data = {"a":
1}
console.log(a) // => {a: 1}これ見ると、不要かも。おまけに、上手く改行してやれば、コンパイル可能。
data = {"a"
:1} // compilation OK!なんと、これでもコンパイル可能。
var add = function(a){
var v = 2
return a + v
}
console.log(add(2)) // => 3
console.log(v) // compilation error, Can't find variable: v以下はvar宣言と同じ、function宣言。
function calc(a){
var v = 101
return v + a
}
console.log(calc(1)) // => 101var宣言同様に、巻き上げが発生する。
console.log(calc(1)) // => 101
function calc(a){
var v = 101
return v + a
}以下はリテラルを使った変数宣言、巻き上げが効かない。
console.log(fact(3)) // in fact(3), fact is undefined
var fact = function(n){
if(n==1){return 1}
return fact(n-1) * n
} 無名関数を変数factにセットしたから?でも無さそう。
console.log(fact(3)) // in fact(3), fact is undefined
var fact = function fact(n){
if(n==1){return 1}
return fact(n-1) * n
} 無名関数をfactへセットしても、再帰呼び出し可能。でも、巻き上げができない。
var fact = function(n){
if(n==1){return 1}
return fact(n-1) * n
}
console.log(fact(3)) // => 6functionリテラル使った変数定義は、var無し変数定義で、巻き上げ効かないのと同じだ。
fact = function(n){
if(n==1){return 1}
return fact(n-1) * n
}
console.log(fact(3)) // => 6ややこしいので、関数定義は、function宣言を使う!巻き上げが効いて、良い感じだし。
new付きだとコンストラクタが呼び出される
date = new Date('2018-07-14'
console.log(typeof date) // => Datenew無しは文字列が返る。Date以外だとstringプリミティブが返る。
date = new Date('2018-07-14')
console.log(typeof date) // => string
str = new String('OK')
console.log(typeof str) // => object, String {0: "N", 1: "G", length: 2} = $2
str = String('OK')
console.log(typeof str) // => string, プリミティブ関数呼び出し中のthisとcall, applyでメソッド呼び出しするときのメソッド中のthisは特殊。 前者は、global, 後者はcall, applyの引数がthisに!
setTimeout, 5sec後にfunc1を一度だけ行う。 setInterval, 5sec後にfunc1繰り返し行う。
func1の中でid = setTimeout(func1, 5000)を呼び出すと、永遠とfunc1が実行され続ける。clearTimeout(id)すれば、止まる。
<script>
var count = 0;
var countup = function(){
console.log(count++);
setTimeout(countup, 1000);
// DEBUG:
debugger;
}
countup();
</script>
画像を貼り付けてみる
前者
bar = 1
var foo = 2
console.log(window.bar) // => 1
console.log(window.foo) // => 2bar, fooの違いは変数宣言の巻き上げ作用が生じるのがfoo、生じないのがbar
後者(Node.js)
bar = 3
var foo = 4
console.log(global.bar) // => 3
console.log(global.foo) // => undefinedvar宣言された変数fooはグローバル・オブジェクトでは無い。巻き上げ作用が生じる、タダのファイル・スコープを持った変数。巻き上げ作用が嫌なので、var宣言を避けてlet宣言する事にする。
MDNサイトの記述には、typo有り(Window => window)
和文の記述には、サンプルコードの記載が無いので、typoを見逃しやすい。