@uents blog

Code wins arguments.

「JavaScript中級講座 〜Ajaxを学ぶ前の基礎知識」を読む(1)

JavaScript 中級講座 ~Ajaxを学ぶ前の基礎知識

一ヶ月ほど前からJavaScriptの勉強をやってます。勉強と言っても、裾野を広げるために「JavaScriptってどんな言語?」というのを漠然と掴む程度が狙いです。将来仕事で使うかもしれないので、今のうちからちょっとは備えておこうかなという位の気持ちでやってます。

ただし、本書を読む前に「JavaScriptプログラミング入門 第2版」をひと通り読んでいるので、右も左も分からない程の超初心者ではありません。知っている所はどんどん飛ばして行くつもり。

§1 JavaScript学習の第ー歩

言語の概要、OS/ブラウザの設定、開発環境などについて。

§2 JavaScriptの基本的な構文

変数の型(オブジェクト)、演算子、関数などについて。

クロージャ (pp.69-71)

クロージャとは、C/C++でいうところの静的変数に当てはまるらしい。
JavaScriptでは局所変数・大域変数は作れるが、静的変数を作るための構文がない。しかし、以下のような無名関数を返す関数を定義することで、静的変数と同等の事が行える。

// カウンタを初期化し、カウントアップする無名関数を返す関数
function initCounter() {
    var count = 0;
    return function() {
        count++;
        return count;
    };
}

呼び出し側のコード。

var countFunc = initCounter();

document.write("count = " + countFunc() + "<br>");
document.write("count = " + countFunc() + "<br>");

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

document.write("count = " + countFunc() + "<br>");

結果は次のようになる。

count = 1
count = 2
count = 13

§3 JavaScript組み込みのオブジェクト

JavaScript本体に予め組み込まれているオブジェクトについて。

オブジェクトとは?(p78)

操作の対象になる「物」の型そのもの。実体ではなくて枠組み。その枠組みの定義がクラス*1

インスタンスコンストラクタ(p79)

オブジェクトの実体がインスタンスインスタンスを作成するもの(関数)がコンストラクタ

プロパティとメソッド(p78)

プロパティはオブジェクトの値や状態を表すもの。メソッドはオブジェクトに大して行う操作。
それぞれ、

インスタンス.プロパティ
インスタンス.メソッド

の形でアクセスできる。もしくは、クラスより

クラス.プロパティ
クラス.メソッド

の形でアクセスすることも可能

文字列のパターンマッチ(pp.97-98)
var str = 'こちらは<a href="http://www.gihyo.co.jp">技術評論社</a>です';
var m = str.match(/<a href="(.*?)">(.*?)<\/a>/);
var msg = "";

// m[0] => パターンに最初にマッチした文字列
// m[1] => 1つ目のカッコにマッチした文字列
// m[2] => 2つ目のカッコにマッチした文字列
for (var i = 0; i < m.length; i++){
    msg += i + " => " + m[i] + " \n";
}

alert(msg);

とすると、実行結果は

0 => <a href="http://www.gihyo.co.jp">技術評論社</a> 
1 => http://www.gihyo.co.jp 
2 => 技術評論社

のようになる。

次に、String.match()メソッドの正規表現にg属性を付けると、

var m = str.match(/<a href="(.*?)">(.*?)<\/a>/g);

実行結果は

0 => <a href="http://www.gihyo.co.jp">技術評論社</a> 

となる。よく分からない。

そこで、オライリーのJavaScript本*2を調べてみると、p216に

Scriptオブジェクトの正規表現メソッドの中で最もよく使われるのが、match()メソッドです。引数に正規表現を指定すると、一致した結果を格納した配列が返されます。
...
正規表現にgフラグがあると、一致した全ての文字列を含む配列を返します。
...
正規表現にgフラグがない場合は、グローバルに検索せずに、最初に一致した文字列だけを返します。ただし、その場合も返されるのは配列です。その場合、配列の1番目の要素は一致した文字列で、残りの要素は正規表現の括弧(())に囲まれた部分表現になります。

とあった。なるほど。

ちなみに、

var m = str.match(/<a href="(.*?)">(.*?)<\/a>/);

var ptn = '<a href="(.*?)">(.*?)</a>'
var r = new RegExp(ptn);
var m = str.match(r);

は、等価。

インスタンスの参照(pp.108-110)

JavaScriptの変数は全て「オブジェクトのインスタンスのリファレンス」である。これだけじゃ何を言ってるか分からないが、Cでいうならポインタ変数みたいな感じ。

例えば、

var a = new Date();
var b = a;
a.setTime(a.getTime() + 3600 * 1000);

document.write("a => " + a.toString() + "<br>");
document.write("b => " + b.toString() + "<br>");

の実行結果は、

a => Sun Mar 29 2009 23:52:27 GMT+0900 (JST)
b => Sun Mar 29 2009 23:52:27 GMT+0900 (JST)

となり、a・bともに1時間ずれる。つまりa、bは同じDateオブジェクトのインスタンスを参照し合っている事を意味する。

関数渡しが間に入るとどうか?

function addOneHour(date){
    date.setTime(date.getTime() + 3600 * 1000);
}

var c = new Date();
var d = c;
addOneHour(c);
document.write("c => " + c.toString() + "<br>");
document.write("d => " + d.toString() + "<br>");

結果は、

c => Sun Mar 29 2009 23:54:49 GMT+0900 (JST)
d => Sun Mar 29 2009 23:54:49 GMT+0900 (JST)

予想通り。

今日はここまで。

*1:たぶん

*2:買っただけで全然読んでません...