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)
  • Null
  • Undefined

数値 (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
  • ''
  • NaN
  • undefined

-1true にキャストされる。

正規表現 (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

Arraylength プロパティで要素数を調べられる。push() で末尾に追加。

関数 (Function)

function funcName() {
    // do something...
}

詳細はまた後で。


予約語

JavaScript の予約語。

  • break
  • case
  • catch
  • continue
  • default
  • delete
  • do
  • else
  • false
  • finally
  • for
  • function
  • if
  • in
  • instanceof
  • new
  • null
  • return
  • switch
  • this
  • throw
  • true
  • try
  • typeof
  • var
  • void
  • while
  • with

変数名などに使用できない。


演算子

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 オブジェクトのインスタンスをスローするのが一般的。

This was posted 2 years ago. It has 50 notes and 0 comments.
  1. webteck reblogged this from null-ly
  2. gx750 reblogged this from null-ly
  3. proto-jp-randomlikes reblogged this from null-ly
  4. kidapu reblogged this from fkei
  5. yasussu reblogged this from null-ly
  6. fkei reblogged this from null-ly
  7. mugyu reblogged this from null-ly
  8. tabito reblogged this from null-ly
  9. speed12 reblogged this from null-ly
  10. wada811 reblogged this from null-ly
  11. k107 reblogged this from null-ly
  12. unkei3 reblogged this from null-ly
  13. resessh-temp reblogged this from null-ly
  14. harax reblogged this from null-ly
  15. eenou reblogged this from null-ly
  16. satsujin reblogged this from null-ly
  17. yang02 reblogged this from null-ly
  18. elliminat reblogged this from null-ly
  19. nmetomo reblogged this from null-ly
  20. uniba reblogged this from null-ly
  21. null-ly posted this