JavaScript 基礎 (Part 1) 資料
公開の勉強会をやったので、その資料を公開。
追記 (2012-06-19 15:40)
syoichi さんからのご指摘を反映
- Boolean にキャストすると
falseになるものに0を追加 - 即値関数 → 即時関数
追記 (2012-06-20 16:15)
@poyoshi さんからのご指摘を反映
- ループの
continueで偶数と奇数が逆になっていたのを修正
自己紹介
- Seiya Konno (@nulltask)
- プログラマ
- ユニバ株式会社所属
目的
今回の目的。
- JavaScript の文法を理解する
今日は特定の処理系 (ブラウザなど) に依存しない JavaScript の言語のみに着目した内容になります。そのため座学っぽくなってしまいますが、お手柔らかに…
次回以降実践を交えながら JavaScript で本格的なオブジェクト指向をやっていく予定です。
対象者
- 新しいプログラミング言語として JavaScript を覚えたい人
JavaScript とは
- 作者: Blendan Eich さん (現 Mozilla CTO)
- 1995 年に Netscape 2.0 とともに登場
- ブラウザ上で動作するスクリプト言語
- 現在は Node.js に代表されるサーバサイドの言語としても注目される
- 動的言語
- プロトタイプベースのオブジェクト指向言語
- クラスはないけど立派にオブジェクト指向ができます
- 名前は似ているが Java とは別物!
構文の特徴
- C 言語に近い平易なシンタックス
- 大文字小文字の区別あり
getName,getname,GETNAMEはそれぞれ別物として扱われる。
- 連続したホワイトスペース (改行, 空白, タブ) は一つにまとめられる。
- 文はセミコロン
;で区切る。
変数
値を格納しておくための識別子。一般的な言語の変数と同じ。
宣言と代入
var 変数名; // 宣言 変数名 = 値; // 代入
宣言時に代入してもよい。
var 変数名 = 値; // 宣言と代入を同時に
宣言時に値を代入しなかった場合、undefined という特別な値になる。
例
var score = 10;
カンマで区切って複数宣言することもできる。
var a = 10,
b = 100,
c = 1000;
- 静的型付け言語と違い、型宣言はしない。
- 型宣言はないが、型はある。
変数名に使える文字
- 英数時
[0-9a-zA-Z] - アンダースコア
_ - ドル記号
$
変数名は数字から始まってはいけない。
var 123abc = 'test'; // NG
コメント
プログラムに注釈を入れることが可能。コメントはインタプリタから無視される。
// 一行コメント
/* 複数行に またがる コメント */
// 次の行は無視される // var a = 10;
型とリテラル
JavaScript で扱う「値」は必ず何かの「型」に従属する。
JavaScript の型
- 数値 (
Number) - 文字列 (
String) - 真偽値 (
Boolean) - オブジェクト (
Object)- 関数 (
Function) - 配列 (
Array) - 日付 (
Date) - 正規表現 (
RegExp) - エラー (
Error)
- 関数 (
NullUndefined
数値 (Number)
整数型 (int)、小数型 (float) の分類はなくて、引っ括めて数値型。
var num1 = 10,
num2 = 10.5,
num3 = 1034;
0x で始まる場合は 16 進数
var hex = 0xFF; // 255
parseInt(), parseFloat() で整数型へキャストする。
var a = parseInt('32', 10); // 32
var b = parseFloat('10.5'); // 10.5
文字列 (String)
var greeting1 = 'hello world',
greeting2 = "hello world";
var genre = 'Rock\'n Roll'; // Rock'n Roll
var tag = "<div class=\"cleafix\"></div>"; // <div class="clearfix"></div>
ダブルクオーテーション " かシングルコーテーション ' のいずれかで括る。どちらでも良い。\ でエスケープする。
String() で文字列へキャストする。
var str = String(10); // "10"
論理値 (Boolean)
var like = true,
hate = false;
Boolean() で論理値へキャストする。
var success = Boolean(1); // true
キャストすると false になるオブジェクト
0(+0,-0)null''NaNundefined
-1 は true にキャストされる。
正規表現 (RegExp)
var pattern = /java(script)?/gi;
pattern.test('Java'); // true
pattern.test('JavaScript'); // true
pattern.test('Objective-C'); // false
RegExp() で正規表現にキャストする。
var regexp = RegExp("Go{2,3}gle"); // /Go{2,3}gle/
null
「値が無い」ことを示す。
var foo = null;
undefined
「値が未定義」であることを示す。
実は変数なので上書きできる。 undefined = 100;
undefined = void 0; // 確実に undefined を得る方法
オブジェクト (Object)
var obj = { a: 10, b: 20, hello: 'world' };
var val1 = obj.a; // 10
ここでの a, b, hello はプロパティと呼ばれる。詳細はまた後で。
配列 (Array)
var arr = [10, 20, 30, 'Hello', 'world']; var val = arr[0]; // 10 var len = arr.length; // 5 arr.push(100); arr.push(200); // arr is [10, 20, 30, 'Hello', 'world', 100, 200] len = arr.length // 7
Array の length プロパティで要素数を調べられる。push() で末尾に追加。
関数 (Function)
function funcName() {
// do something...
}
詳細はまた後で。
予約語
JavaScript の予約語。
breakcasecatchcontinuedefaultdeletedoelsefalsefinallyforfunctionifininstanceofnewnullreturnswitchthisthrowtruetrytypeofvarvoidwhilewith
変数名などに使用できない。
演算子
JavaScript の演算子は C や Java と同様のスタイル。
算術演算子
整数型同士の演算。
足し算 (+)
var a = 10 + 20; // 30
引き算 (-)
var a = 10 - 20; // -10
掛け算 (*)
var a = 10 * 20; // 200
割り算 (/)
var a = 10 / 20; // 0.5
ゼロ 0 で割ると Infinity もしくは -Infinity という特別な値となる。
割った余り (%)
var a = 5 % 3; // 2
ゼロで割った余りは NaN (Not a Number) という特別な値となる。
インクリメント・デクリメント
整数型を 1 ずつ加算 or 減算。
var a = 0; a++; // 1 a++; // 2
var a = 100; a--; // 99 a--; // 98
++a や --a とも書ける。
代入演算子
変数に値を代入する。
var a = 10; a += 100; // 110 (a = a + 100; と同様) a -= 50; // 60 (a = a - 50; と同様)
+=, -= で代入と演算を同時に出来る。
比較演算子
ふたつの式を比較する。比較結果が正しければ true, そうでない場合 false と評価される。
a == b; // 一致 a === b; // 完全に一致 a != b; // 一致しない a > b; // a は b より大きい a >= b; // a は b より大きいか等しい a < b; // a は b 未満 a <= b; // a は b 以下
== と === の違い。
'10' == 10 // true '10' === 10 // false
== は比較時に型変換を行う。=== は型変換を行わない。
文字列連結子 (+)
文字列同士の連結。
var message = 'hello'; message = message + ', world.'; // 'hello, world.' message += ' everyone!'; // 'hello, world. everyone!'
論理演算子
var a = true, b = false, c = true, d = false; a && b; // false a && c; // true a || b; // true b || d; // false !(a && b); // true !(b || d); // true
&& は比較するすべての値が true であれば true, || は比較する値が一つでも true であれば true。
三項演算子
条件によって代入する値を変更することができる。
var child = (age <= 18) ? "yes" : "no";
演算子の優先順位
var a = 1 + 2 * 3; // 2 * 3 が優先される var b = (1 + 2) * 3; // カッコを使って優先順位を変更できる
制御文 : 分岐
JavaScript の分岐は C や Java と同様のスタイル。
if 文
条件によって処理を分岐する。
if (a > b) {
// a が b よりも大きいとき
} else {
// a は b 以下
}
条件を複数書くこともできる。
if (a > b) {
// a が b よりも大きい時
} else if (a > c) {
// a が c よりも大きい時
} else {
// それ以外の時
}
switch 文
複数が複数存在する場合に有用。
switch (char) {
case 'a':
// do something if char is 'a'
break;
case 'b':
// do something if char is 'b'
break;
case 'c':
// do something if char is 'c'
break;
case 'd':
// do something if char is 'd'
break;
case 'e':
case 'f':
// do something if char is 'e' or 'f'
break;
// 何にも一致しなかった時
default:
break;
}
break を書かない場合はフォールバックする。
switch (num) {
case 1:
// do something if num is 1
break;
case 2:
// do something if num is 2
case 3:
// do something if num is 2 or 3
case 4:
// do something if num is 2 or 3 or 4
default:
// do something if num is not 1
}
制御文 : ループ
JavaScript のループ文は C や Java と同様のスタイル。
for 文
var sum = 0;
for (var i = 0; i < 10; i++) {
sum = sum + (i * 10);
}
while 文
var i = 0,
sum = 0;
while (i < 10) {
sum = sum + (i * 10);
i++;
}
do-while 文
var i = 0,
sum = 0;
do {
sum = sum + (i * 10);
} while (i < 10);
ループ内で break を実行するとループを終了させることができる。
var i = 0;
while (true) { // 無限ループ
if (i > 5) {
break; // i が 5 より大きくなったらループを中断
}
}
ループ内で continue を実行するとそのループをスキップし後続のループを処理する。
var i = 0;
for (i = 0; i < 10; i++) {
if (i % 2) {
continue; // 奇数の場合はスキップ
}
// 偶数の時だけここに行く
// do something
}
オブジェクト
JavaScript のオブジェクトは「プロパティ」と「値」のペアで表現される。
var obj = {
a: 10,
b: 20,
c: 30
};
次のように書くこともできる。
var obj = {};
obj.a = 10; // ドットシンタックス
obj.b = 20;
obj['c'] = 30; // 連想配列風
ネストすることもできる。
var my = {
namespace: {
foo: 'baz'
}
};
my.namespace.foo; // 'baz'
my['namespace'].foo; // 'baz'
JavaScript のオブジェクトはネームスペースの生成や連想配列として使うこともできる。
オブジェクトにプロパティが存在するか調べるには in 演算子を使う。
var obj = {
a: 10,
b: 20
};
var res1 = 'a' in obj; // true
var res2 = 'z' in obj; // false
for-in ループでプロパティを列挙できる。
var obj = {};
obj.foo = 10;
obj.bar = 20;
obj.baz = 30;
for (var p in obj) {
obj[p];
}
関数
ここでは一般的な関数の振る舞いについて説明する。
定義
function キーワードを使って関数を定義する。
function funcName() {
// do something
}
return で戻り値を返すことができる。return した時点で関数の処理は終わる。
function max(a, b) {
if (a > b) {
return a;
}
return b;
}
呼び出し
関数名に () をつけることで呼び出すことができる。
funcName();
引数を指定することができる。
funcName(a, b);
代入式で戻り値を取得できる。
var result = max(10, 20);
自分自身を呼び出すこともできる。(再帰呼び出し)
function pow(n) {
if (n == 0) {
return 1;
}
return pow(n - 1) * n;
}
var result = pow(5); // 120 (5!)
JavaScript の関数
JavaScript の関数の面白い特徴。
- 関数そのものを値として使うことができる
- C などの関数ポインタ (のようなもの)
- 名前の無い関数を作ることができる (無名関数)
- 関数はスコープを生成する
- 関数の中に関数を定義できる
- クロージャを作ることができる
- 関数に
newキーワードを使ってオブジェクトを生成することもできる
関数を値として使う例
宣言した関数を変数に代入しちゃう。
function funcName() {
// do something
}
var fn = funcName; // 変数に代入
fn(); // 呼び出し
関数を引数として渡せちゃう。
function funcName(callback) {
// do something...
callback();
}
function callbackFunc() {
// run after `funcName`
}
funcName(callbackFunc);
名前の無い関数 (無名関数)
var fn = function() {
// do something...
};
fn(); // 呼び出し
以下はよくある一例。無名関数をそのまま関数の引数として渡す。
function doSomething(callback) {
// do something…
callback();
}
doSomething(function() {
// run after `doSomething`
});
無名関数をいきなり実行しちゃう。(即時関数)
(function() {
// run anonymous function
})();
オブジェクトと組み合わせちゃう。
var obj = {
max: function(a, b) {
if (a > b) {
return a;
}
return b;
},
min: function(a, b) {
if (a > b) {
return b;
}
return a;
}
};
obj.max(10, 20); // 20
obj.min(10, 20); // 10
関数はスコープを生成する
関数の中の変数には関数の外側からは参照できない。
function foo() {
var a = 100;
}
var baz = a; // baz === undefined
関数の中に関数を定義する。
function foo() {
// outer function
function bar() {
// inner function
function baz() {
// super inner function
}
}
}
外側の関数の値は参照できる。外側からはできない。(レキシカルスコープ)
function outer() {
var a = 10,
b = 20;
function inner() {
var c = a; // c == 10
}
inner();
var x = c; // x === undefined
}
関数外で変数を宣言した場合はグローバルオブジェクトに定義される。(グローバル汚染)
var a = 10, b = 20; // どこからでも参照できてしまう
function() {
var c = a,
d = b; // c == 10, d == 20
}
即値関数を応用してグローバル汚染を回避する。
(function() {
var a = 10,
b = 20;
})();
カプセル化っぽいことも。
function capsule() {
var himitsu1 = 10,
himitsu2 = 20;
return function(a, b) {
return a + b + himitsu1 + himitsu2;
};
}
var fn = capsule();
var result = fn(100, 200); // result == 330
変数 himitsu1, himitsu2 の存在が隠蔽される。
クロージャを作る
function closure() {
var n = 0;
return function() {
n++;
return n;
};
}
var fn = closure();
var res1 = fn(), // 1
res2 = fn(), // 2
res3 = fn(); // 3
関数内の n の値が保持されつづける。
キーワード new で関数からオブジェクトを生成
function Person(name, age) {
this.name = name;
this.age = age;
this.introduce = function() {
return 'My name is ' + this.name + '. I\'m ' + age ' years old.';
};
}
var alice = new Person('Alice Liddel', 10),
bob = new Person('Bob Dylan', 71);
var introOfAlice = alice.introduce(); // 'My name is Alice Liddel. I'm 10 years old.'
var introOfBob = bob.introduce(); // 'My name is Bob Dylan. I'm 71 years old.'
alice.sayAboutFuture = function(n) {
return n + ' years after, my age will be ' + (this.age + n) + '.';
};
var future = alice.sayAboutFuture(90); // '90 years after, my age will be 100.'
- コンストラクタとして振る舞う関数
Personをコンストラクタ関数と呼ぶ - コンストラクタ関数は慣例的に大文字からはじめる
newを使って関数を呼び出す場合、thisは生成されたオブジェクト自身の参照となる- アクセス修飾子は存在しない
- すべて
public扱い (alice.age = 100;ができてしまう!!)
- すべて
- あとからプロパティを追加することができる
カプセル化や継承などの踏み込んだ話は次回!
例外処理
Java の例外と同様のスタイル。
捕捉
try {
// do something.
// 例外が起きるかもしれないコード
} catch (e) {
// 例外が起きた時に実行される
// e にスローされたオブジェクトが渡される
} finally {
// 例外が起きても起きなくても必ず実行される
}
finally は書かなくても良い。
例外のスロー
try {
if (Math.random() % 2) {
throw new Error('なにか起きた');
}
// do something...
} catch (e) {
// e.message でエラーメッセージを取得できる
}
Error オブジェクトにかぎらず、なんでもスローできるが、原則として Error オブジェクトのインスタンスをスローするのが一般的。
-
watabon likes this
-
sakinomemo likes this
-
gx750 reblogged this from null-ly
-
proto-jp-randomlikes reblogged this from null-ly
-
kidapu reblogged this from fkei
-
yasussu reblogged this from null-ly
-
fkei reblogged this from null-ly
-
been likes this
-
asefujiko likes this
-
tsuwatch likes this
-
mugyu reblogged this from null-ly
-
shin-sapporo likes this
-
tabito reblogged this from null-ly
-
speed12 reblogged this from null-ly
-
wada811 reblogged this from null-ly
-
fingaholic likes this
-
gomiboot likes this
-
k107 reblogged this from null-ly
-
owswiss likes this
-
hiromitsuuuuu likes this
-
yohawing likes this
-
unkei3 reblogged this from null-ly
-
resessh reblogged this from null-ly
-
resessh likes this
-
hirosis likes this
-
harax reblogged this from null-ly
-
pocketskumi likes this
-
cafoff likes this
-
eenou reblogged this from null-ly
-
naoki-den likes this
-
psmatome reblogged this from null-ly
-
syoichi likes this
-
satsujin reblogged this from null-ly
-
yang02 reblogged this from null-ly
-
elliminat reblogged this from null-ly
-
youtalk likes this
-
proto-jp likes this
-
nmetomo reblogged this from null-ly
-
nmetomo likes this
-
oppei likes this
-
atm09td likes this
-
uniba reblogged this from null-ly
-
kazupon likes this
-
null-ly posted this