69
スコープの話

Miyazaki.js vol.1 スコープの話

Embed Size (px)

DESCRIPTION

2014/10/18 Miyazaki.js vol.1 スコープの話

Citation preview

Page 1: Miyazaki.js vol.1 スコープの話

スコープの話

Page 2: Miyazaki.js vol.1 スコープの話

自己紹介

Nobuhiro Nakashima @ombran JavaScript/Ruby/サンホラ/アニオタ 株式会社アラタナ エンジニア Miyazaki.js主催

Page 3: Miyazaki.js vol.1 スコープの話

スコープ

Page 4: Miyazaki.js vol.1 スコープの話

– by Wikipedia

“ある変数や関数が

特定の名前で参照される範囲のこと”

スコープ

Page 5: Miyazaki.js vol.1 スコープの話

スコープの種類

Page 6: Miyazaki.js vol.1 スコープの話

global scope プログラム「全体」から見えるスコープ

file scope プログラムを記述したファイルの内側でのみ参照できるスコープ

local scope ある関数やブロックの範囲内に限定されたスコープ

instance scope いわゆるカプセル化

class scope あるクラスの定義全体から参照できるスコープ

Page 7: Miyazaki.js vol.1 スコープの話

global scope プログラム「全体」から見えるスコープ

file scope プログラムを記述したファイルの内側でのみ参照できるスコープ

local scope ある関数やブロックの範囲内に限定されたスコープ

instance scope いわゆるカプセル化

class scope あるクラスの定義全体から参照できるスコープ

JavaScript

でのスコープ

Page 8: Miyazaki.js vol.1 スコープの話

スコープの例

Page 9: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); // > undefined var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" (ローカル変数を参照)

console.log(scope); // > "Global" (グローバル変数を参照)

Page 10: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); // > undefined var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" (ローカル変数を参照)

console.log(scope); // > "Global" (グローバル変数を参照)

global scope

Page 11: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); // > undefined var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" (ローカル変数を参照)

console.log(scope); // > "Global" (グローバル変数を参照)

local scope

Page 12: Miyazaki.js vol.1 スコープの話

スコープの話の前に 変数の前のやつを説明します

Page 13: Miyazaki.js vol.1 スコープの話

varについて

Page 14: Miyazaki.js vol.1 スコープの話

varなし→必ずグローバル

varあり→スコープ内変数

varは絶対付けること

Page 15: Miyazaki.js vol.1 スコープの話

スコープをもうちょっと深く

Page 16: Miyazaki.js vol.1 スコープの話

global scope

• functionの外で宣言された変数・関数

• varなしで宣言された変数

Page 17: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); // > “Global” scope = "Global2"; return scope; }

console.log(getValue()); // > "Global2" console.log(scope); // > "Global2"

functionの外で宣言

Page 18: Miyazaki.js vol.1 スコープの話

function getValue() { scope = "Global2"; return scope; }

console.log(getValue()); // > "Global2" console.log(scope); // > "Global2"

varなしで宣言

Page 19: Miyazaki.js vol.1 スコープの話

local scope

• functionの中で宣言された変数・関数

• functionの引数で宣言された変数

Page 20: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); // > undefined var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" console.log(scope); // > "Global"

functionの中で宣言

Page 21: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue(arg1) { console.log(arg1); // > “Global” arg1 = "Local"; return arg1; }

console.log(getValue(scope)); // > "Local" console.log(scope); // > "Global"

functionの引数で宣言

Page 22: Miyazaki.js vol.1 スコープの話

なぜこういう挙動をするのか

Page 23: Miyazaki.js vol.1 スコープの話

スコープチェーン

Page 24: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

ここの変数の値を探すルール

Page 25: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

Cはこのスコープで見つかる

Page 26: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

Bはこのスコープで見つかる

Page 27: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

Aはこのスコープで見つかる

Page 28: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

変数の 検索範囲が徐々に広がっている

Page 29: Miyazaki.js vol.1 スコープの話

これが スコープチェーン

Page 30: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" console.log(scope); // > "Global"

さっきのやつ

この時点で同一スコープを探す

Page 31: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { console.log(scope); var scope = "Local"; return scope; }

console.log(getValue()); // > "Local" console.log(scope); // > "Global"

さっきのやつ

この時点で同一スコープを探す

いた!!

Page 32: Miyazaki.js vol.1 スコープの話

なぜundefined?

Page 33: Miyazaki.js vol.1 スコープの話

var scope = "Global";

function getValue() { var scope; console.log(scope); // > undefined scope = "Local"; return scope; }

console.log(getValue()); // > "Local" console.log(scope); // > "Global"

こういうイメージ

Page 34: Miyazaki.js vol.1 スコープの話

だから変数は最初に 全部書きましょう

Page 35: Miyazaki.js vol.1 スコープの話

スコープチェーン による強力な機能

Page 36: Miyazaki.js vol.1 スコープの話

の前に ちょっと最新の話

Page 37: Miyazaki.js vol.1 スコープの話

ちなみに Javaなどにある

ブロックスコープですが

Page 38: Miyazaki.js vol.1 スコープの話

var sum = 0;

for (var i = 0; i < 10; i++) { sum += i; }

console.log(sum); console.log(i);

ブロックスコープ

Page 39: Miyazaki.js vol.1 スコープの話

var sum = 0;

for (var i = 0; i < 10; i++) { sum += i; }

console.log(sum); // > 45 console.log(i); // > ??

ブロックスコープ

Page 40: Miyazaki.js vol.1 スコープの話

var sum = 0;

for (var i = 0; i < 10; i++) { sum += i; }

console.log(sum); // > 45 console.log(i); // > ReferenceError 10

ブロックスコープ

Page 41: Miyazaki.js vol.1 スコープの話

var sum = 0;

for (var i = 0; i < 10; i++) { sum += i; }

console.log(sum); // > 45 console.log(i); // > ReferenceError 10

ブロックスコープ

Page 42: Miyazaki.js vol.1 スコープの話

ECMAScript6の新機能

letでできるよ

Page 43: Miyazaki.js vol.1 スコープの話

var sum = 0;

for (let i = 0; i < 10; i++) { sum += i; }

console.log(sum); // > 45 console.log(i); // > ReferenceError

ブロックスコープ

Page 44: Miyazaki.js vol.1 スコープの話

戻ります

Page 45: Miyazaki.js vol.1 スコープの話

スコープチェーン による強力な機能

Page 46: Miyazaki.js vol.1 スコープの話

クロージャ

Page 47: Miyazaki.js vol.1 スコープの話

– by Wikipedia

“引数以外の変数を実行時の環境ではなく、 自身が定義された環境(静的スコープ)において解決することを特徴とする。”

クロージャ

Page 48: Miyazaki.js vol.1 スコープの話
Page 49: Miyazaki.js vol.1 スコープの話

var a = “GlobalA”; var b = “GlobalB”;

function func1() { var b = “Func1B”;

function func2() { var c = “Func2C”;

console.log(c); // > “Func2C” console.log(b); // > “Func1B” console.log(a); // > “GlobalA” } func2(); } func1();

さっきのも クロージャ

Page 50: Miyazaki.js vol.1 スコープの話

クロージャの 実践例

Page 51: Miyazaki.js vol.1 スコープの話

function counter() { var count = 0;

return function() { count = count + 1; return count; } }

var cnt = counter(); console.log(cnt()); // > 1 console.log(cnt()); // > 2 console.log(cnt()); // > 3

変数の 永続化

Page 52: Miyazaki.js vol.1 スコープの話

function counter() { var count = 0;

return function() { count = count + 1; return count; } }

var cnt = counter(); console.log(cnt()); // > 1 console.log(cnt()); // > 2 console.log(cnt()); // > 3

変数の 永続化

ここで変数が束縛される

Page 53: Miyazaki.js vol.1 スコープの話

function counter() { var count = 0;

return function() { count = count + 1; return count; } }

var cnt = counter(); console.log(cnt()); // > 1 console.log(cnt()); // > 2 console.log(cnt()); // > 3

変数の 永続化

束縛されたままなので 値がインクリメントされる

Page 54: Miyazaki.js vol.1 スコープの話

即時関数

Page 55: Miyazaki.js vol.1 スコープの話

function helloWorld() { alert("Hello, World!"); } helloWorld();

普通の関数定義と実行

Page 56: Miyazaki.js vol.1 スコープの話

(function helloWorld() { alert("Hello, World!"); })();

即時関数

定義後、即実行

Page 57: Miyazaki.js vol.1 スコープの話

メリット

Page 58: Miyazaki.js vol.1 スコープの話

グローバルスコープを 汚さない

Page 59: Miyazaki.js vol.1 スコープの話

(function helloWorld() { alert("Hello, World!"); })();

helloWorld(); // > エラー

即時関数

Page 60: Miyazaki.js vol.1 スコープの話

ということは 関数名もいらない

Page 61: Miyazaki.js vol.1 スコープの話

(function() { alert("Hello, World!"); })();

即時関数

無名関数

Page 62: Miyazaki.js vol.1 スコープの話

どういう時に使うか

Page 63: Miyazaki.js vol.1 スコープの話

(function() { var hoge = 1; function fuga() { console.log(hoge); } fuga(); })();

ファイル内の全コードを囲む

Page 64: Miyazaki.js vol.1 スコープの話

なにがうれしい?

Page 65: Miyazaki.js vol.1 スコープの話

グローバルスコープを 汚さない

Page 66: Miyazaki.js vol.1 スコープの話

同一ページで 複数JSファイルを 読み込んでも

他のJSを壊さない

Page 67: Miyazaki.js vol.1 スコープの話

(function() { // ここに自分の

//JavaScriptコードを書く

})();

Page 68: Miyazaki.js vol.1 スコープの話

(function() { // ここに自分の

//JavaScriptコードを書く

})();

マナーとして覚えてください

Page 69: Miyazaki.js vol.1 スコープの話

fin