javascripterになろう。の巻
1章

yusuke

Press key to advance.
Zoom in/out: Ctrl or Command+ +/-

章 1

  • 基礎(introduction)
  • クロージャ(closure)
  • レキシカルスコープ(lexical scope/static scope)
  • ブロック(block scope)

章 2

  • 高階関数(higher-order function)
  • カリー化(currying)
  • メモ化(memoize)
  • 非同期:遅延(defered)
  • プロトタイプ(prototype)

章 3

  • Argument について
  • Function.prototype{apply/call}とdelegate
  • Array.prototype
  • javascript 1.6

1章が30分で終わればいいとこの予定

是非、手元のjavascript engine(browser)でtrying!

※ alertか、debugモードでの実行を推奨

第一章

  • 基礎(introduction)
  • クロージャ(closure)
  • レキシカルスコープ(lexical scope/static scope)
  • ブロック(block scope)

introduction 基礎

基礎の基礎はすっ飛ばします

introduction 変数とは

変数について

var a = "hello world";
a.substring(6); // => world

"hello world".substring(6); // => world

は同じ結果になるのは解りますよね

もちろん

var a = 1;
var b = 2;

a + b + 3; // => 6

にもなるし、

1 + 2 + 3; // => 6

というのはわかります。

ということは、

var a = [100, 200, 300, 400, 500];
a[0]; // => 100
a[3]; // => 400

にもなるし、

[100, 200, 300, 400, 500][0]; // => 100
[100, 200, 300, 400, 500][3]; // => 400

というのはわかります。

ということは、

var a = [100, 20, 3];
a.sort(function (x, y){ return x < y ? -1 : 1}); // ascending
// 3, 20, 100

[100, 20, 3].sort(function (x, y){ return x < y ? -1 : 1}); // ascending
// 3, 20, 100

も同じ結果になる

ということは、

変数は 「値」 への alias (参照)である

と、いうこと。

もっというと、

変数は 「値」 への名前(label)付き参照(alias) である

と、いうこと。

var hoge = [1,2]; は
hoge という label に 値 [1,2] を参照しているということ

introduction 型

javascriptの値は主に下記の型しかない※1

  • Number
  • Boolean
  • String
  • Date
  • Function
  • Array(complex)
  • Object(any)
  • その他(Error, RegExp, null, undefined...)

ということは、

var a = function(msg){
  return msg + 'だよね';
};
a('hello world'); // => hello worldだよね

になり、

function a(msg){
  return msg + 'だよね';
}
a('hello world2'); // => hello world2だよね

となる

introduction シンタックスシュガー

syntax suger, syntactic sugar とか

ようするに

var a = new Array(3);
a.push(1, 2, 3);

var a = [1, 2, 3];

に記述できるように、別の記法があるということ

var a = {
  hoge: 'hello',
  foo: 'world',
  bar: 'hello world'
};

は、下記のシンタックスシュガーです

var a = new Object();
a.hoge = 'hello';
a.foo = 'world';
a.bar = 'hello world';

無名関数(匿名関数)

function aaa(){
  // code...
}
aaa('hello world');

var aaa = function (){
  // code...
}
aaa('hello world');

のどちらも、関数定義を行っているが、後者は関数名が存在しない匿名関数となる

function aaa(){}
alert(aaa.name); // => aaa

var bbb = function (){};
alert(bbb.name); // => undefined

関数に名前をつけることで、「名前付き関数」と読んだり

var a = new Function('x, y', 'return x + y');
a(1, 2); // => 3
alert(a.name); // => anonymous

(省略)

クロージャ(closure)

クロージャとは、

単なる関数ではなく、その関数が定義された環境への参照を持った関数のこと

これがクロージャ

var createCounter = function (){
  var count = 0;
  return function (){
    return count++;
  };
};
var a = createCounter();
a(); // => 0
a(); // => 1

var b = createCounter();
b(); // => 0
b(); // => 1

a(); // => 2

createCounter を行った時点での変数 counter の値を保持した関数 => closure

closureはスコープを持つ

var a = 1;
var hoge = function (){
  var a = 123;
  alert(a); // => 123
};
hoge();
alert(a) // => ???

結果は 1 と表示されます

closureはスコープを持つ

var a = 1; // <<= Global のスコープ
var hoge = function (){
  var a = 123; // <<= hoge func のスコープ
  alert(a); // <== hoge func のスコープにある変数 a を表示
};
hoge();
alert(a) // <<= Global のスコープにある変数 a を表示

var で宣言された変数は、スコープを持つ

レキシカルスコープ

スコープの範囲のこと

var hoge = function (){
  var a = 'hello';
};
var foo = function (){
  var a = 'world';
};
var a = 'hello world';

これらの変数a はすべて違うスコープを持っている

レキシカルスコープに変数が見つからない場合に外側のスコープを参照する

var a = 'hello world';
var hoge = function (){
  alert(a);
};
hoge(); // => ?

本来 hoge の関数無いには存在しないハズの 変数a の参照が行われている。

これはレキシカルスコープによって var a;の参照できる範囲が、 hoge の関数にも存在していることと同等

レキシカルスコープ - レシーバ

レシーバとは、オブジェクトにおいてメッセージの送信元のこと

つまり

var d = new Date();
d.getTime();

このコードにおける変数 d は getTime メッセージ(getTime() メソッドの呼び出し) のレシーバである)

レキシカルスコープで間違いやすいのは、prototypeの参照(親クラスの参照である)

var d = new Date;
d.toUTCString(); // => Tue, 08 Mar 2011 15:45:53 GMT

var hoge = {};
hoge.toString(); // => [object Object]

alert(setTimeout); // => ?
alert(window.setTimeout); // => ?

toString などのように、親クラスから継承したものはレキシカルスコープの参照とは呼ばれない

レシーバとなるオブジェクトの参照を行うのがレキシカルスコープとなる(※注1 window(global) null)

ブロック

ブロックとは "ある" 変数の 参照領域のことである

JavaやC++などの言語は { から } までが一つのブロックとなっている

// java
String hoge = "hello";
String hoge = "world"; // compile error!

となってしまうコードは

{
  String hoge = "hello";
}
{
  String hoge = "world";
}

{ と } のブロックで囲う場合、ブロックによって、変数の参照が変わるのでエラーにならない

javascript において、ブロックは with もしくは function がブロックとなる

(function (){
  alert(hoge); // => undefined
  var hoge = 'hello';
  alert(hoge); // => hello
})();

with({}){
  alert(hoge); // => undefined
  var hoge = 'world';
  alert(hoge); // world
}

with はとても危険なコードとなる可能性がある(※注1)があるので、 ここでは、function がブロックとなる とだけ、覚えればよい

第二章へ

to be continued...