yusuke
Press →key to advance.
Zoom in/out: Ctrl or Command+ +/-
1章が30分で終わればいいとこの予定
是非、手元のjavascript engine(browser)でtrying!
※ alertか、debugモードでの実行を推奨
基礎の基礎はすっ飛ばします
変数について
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] を参照しているということ
javascriptの値は主に下記の型しかない※1
ということは、
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
クロージャとは、
単なる関数ではなく、その関数が定義された環境への参照を持った関数のこと
これがクロージャ
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...