Skip to content

Instantly share code, notes, and snippets.

@externvoid
Last active August 20, 2018 00:00
Show Gist options
  • Select an option

  • Save externvoid/e3b8f86c821f32b8dc12dcc6a3dab272 to your computer and use it in GitHub Desktop.

Select an option

Save externvoid/e3b8f86c821f32b8dc12dcc6a3dab272 to your computer and use it in GitHub Desktop.
JavaScriptの混乱ポイント

JavaScriptの混乱ポイント

Safari(11.1.1)@Sierra(10.12.6, final Sierra)のdev tool, consoleで確認

変数宣言keyword 'var'無しでもglobal変数宣言可能

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!

なんと、これでもコンパイル可能。

奇妙な事に関数内local変数をkeyword varで作れる

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

function宣言(文)

以下はvar宣言と同じ、function宣言。

function calc(a){
  var v = 101
  return v + a
}
console.log(calc(1)) // => 101

var宣言同様に、巻き上げが発生する。

console.log(calc(1)) // => 101
function calc(a){
  var v = 101
  return v + a
}

functionリテラルとfunction宣言(文)

以下はリテラルを使った変数宣言、巻き上げが効かない。

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)) // => 6

functionリテラル使った変数定義は、var無し変数定義で、巻き上げ効かないのと同じだ。

fact = function(n){
  if(n==1){return 1}
  return fact(n-1) * n
}
console.log(fact(3))  // => 6

ややこしいので、関数定義は、function宣言を使う!巻き上げが効いて、良い感じだし。

new付きオブジェクト生成

new付きだとコンストラクタが呼び出される

date = new Date('2018-07-14'
console.log(typeof date) // => Date

new無しは文字列が返る。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は4種類ある

こいつがわかりやすい

関数呼び出し中のthisとcall, applyでメソッド呼び出しするときのメソッド中のthisは特殊。 前者は、global, 後者はcall, applyの引数がthisに!

setTimeoutの使い方

setTimeout, 5sec後にfunc1を一度だけ行う。 setInterval, 5sec後にfunc1繰り返し行う。

func1の中でid = setTimeout(func1, 5000)を呼び出すと、永遠とfunc1が実行され続ける。clearTimeout(id)すれば、止まる。

setTimeoutの使い方

<script>
  var count = 0;
  var countup = function(){
    console.log(count++);
    setTimeout(countup, 1000);
    // DEBUG:
    debugger;
  }
  countup();
</script>

SetTimeout

画像を貼り付けてみる

JavaScript のグローバル・オブジェクトはWebブラウザ環境とNode.js環境で異なる

前者

bar = 1
var foo = 2
console.log(window.bar) // => 1
console.log(window.foo) // => 2

bar, fooの違いは変数宣言の巻き上げ作用が生じるのがfoo、生じないのがbar

後者(Node.js)

bar = 3
var foo = 4
console.log(global.bar) // => 3
console.log(global.foo) // => undefined

var宣言された変数fooはグローバル・オブジェクトでは無い。巻き上げ作用が生じる、タダのファイル・スコープを持った変数。巻き上げ作用が嫌なので、var宣言を避けてlet宣言する事にする。

MDNサイトの記述には、typo有り(Window => window)

和文の記述には、サンプルコードの記載が無いので、typoを見逃しやすい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment