関数の最後に () がつく時とつかない時の違い

現在時刻を表示させ、それをリアルタイムに更新していくコードを書いてみたときに一つの疑問が。
関数の最後に () がつくときとつかない時の違いってなんだろう?
例えばこれ。

var tid = setInterval(displayTime, 200);
function displayTime(){
	var now = new Date();
	document.getElementById("now").innerHTML = now.toLocaleString();
}

1 行目の displayTime は () をつけると動かない。
今まで関数はなんでも最後に () をつけて書いてきていたので疑問を覚えた。
で、とても参考になったのが 関数の呼び出しかた 【OKWave】
関数を実行させたいときは () をつけ、単純に参照先を渡したいときは () がいらないらしい。
この説明があってとても助かった〜。

Window オブジェクト勉強中にハマった問題

ついにきた。ものすごいどっぷりとハマってしまった Window オブジェクトに関するある問題。
なんとか解決してうまくいったので今ものすごい達成感に満ち満ちているけど、でも勉強そのものは今日一日全然進んでない!解決したから嬉しいけど!
さて、その問題とは。

chrome で window.focus が動かない

テキストにあった簡単なコードがこれ。

var child = window.open("http://google.com", "child");
window.focus();

単純にウィンドウを新しく生成したあと、focus を元々のウィンドウにあてるというもの。単純。
なのに動かない。ウィンドウ生成まではうまくいったけど、フォーカスは新しいウィンドウにあたったまま。
自分の書き方がいけないのか?と思ってサンプルコードをそのままコピペしても動かず。
ググってみると setTimeout() を使えとか、blur() を使ったあとに focus() を使えとか、色々書いてあったけど試してみてもどれもうまくいかず。
そうこうしているときに stackoverflow で似たような現象が言及されているのを発見。
リンクをたどってみると、まさにこれだ!!!
Issue 1383 - chromium - window.focus from child window does not put focus back on the parent (opener) window. - An open-source project to help move the web forward. - Google Project Hosting
ちゃんと解決はしていないものの、回避策が書かれている。

javascript - window.focus() not working in Google Chrome - Stack Overflow
これに従うと、要は新しく元のウィンドウと同じ要素を持つウィンドウを作成して、元のウィンドウを閉じれば見せかけはうまくいくよ、とのこと。
(ちなみに問題発生からここに辿り着くまでに3時間ぐらいかかっている…)
これを書いてくれた人にものすごく感謝しつつその通りに書いてみたけど、動かない…。

function refocusWindow() {
  var newName = window.name + '-2'; // you'll want to customize this for your needs
  var options = ''; // again, customize for your situation
  var w = window.open('', newName, options);
  var elements = document.getElementById("everything").innerHTML;
  w.document.write(elements);
  window.close();
}  

の elements 取得のところで null の innerHTML なんてとれないよ、って言われる。
id は body に振ってあるしはてさて、と考えたところ、おそらくではあるけど document に元ウィンドウの要素が格納される前に getElementById() をしにいってしまっているのではないか、ということに辿り着き(ここでもいろんな Q&A サイトを参考にしました。先人の皆さんありがとう!!)、id を降るときに onload() を足してみた。

<body id = "everything" onload="refocusWindow();">

これでようやく思い通りに動いた!!!
こういった問題を克服した時の達成感ってコーディングの醍醐味だと思う。本当に。
でもこれにかまけていてテキストは全然進まなかった…。

オブジェクトちょっとわかるようになった!

年末だけど引き続き JavaScript。けどガキ使見ながら勉強していたらやっぱり理解度とか集中してやるのに比べると全然ダメだったから、明日からはやっぱりテレビとか見るのはやめよう。

知ったこと

eval() 関数

文字列を JavaScript として実行してくれる。
使い道の想像がまだ出来ないけど、なんとなく便利そうな雰囲気は感じる。

インスタンスコンストラクタ

個々のオブジェクトがインスタンスと呼ばれ、インスタンスを作成して初期化するのがコンストラクタ

var arr = new Array();

と書いたら、
× Array オブジェクトのインスタンス arr を作成
◯ Array オブジェクトのインスタンスを作成して arr に割り当て
この割り当てというのが重要で、あくまで値ではなく参照しているからこういう言い方になるんじゃないかな。

ラッパー

コアオブジェクトのうち、Number / String / Boolean の 3 つはプリミティブ型に対応している。
これらにおいては基本的にインスタンスは使わないが、メソッドを使うことができる。
何が起きているのかというと、これらについてメソッドを呼び出すと対応するラッパークラスのオブジェクトが自動的に生成される。

文字列操作

パターンマッチ

match を使うときに g フラグを立てないと、パターンに最初にマッチした文字列が返される。
ここで括弧をつかっていると、括弧に相当する部分も返される。
g フラグを立てるとすべてのマッチする部分が返される。

replace でのキャプチャ
var str2 = "textJavatextJavatextJava";
var reg2 = new RegExp("(text|Java)", "g");
msg2 = str2.replace(reg2, "<b>$1</b>");

のようにキャプチャした部分を $1 に置き換えることができる。

function オブジェクトの作りかた。

1つめ。

x = new Function("arg[0]", "arg[1]", "return arg[0] + arg[1];");

2つめ。

x = function(arg[0], arg[1]){
    return arg[0] + arg[1];
}

値渡しと参照渡し、クロージャ

引き続き JavaScipt 中級講座。これ、取っ付きにくいところも少なく、説明がわかりやすくて丁寧で、で、意外と細かいところも色々と説明してあって良い良い。

学んだこと

値渡しと参照渡し

変数を渡すときは値渡しだけど、オブジェクトを渡すときは参照渡しとなる。

実際にこんなの書いて実行してみたらとてもわかりやすかった。

function variable_pass(y) {
	y ++;
}
function object_pass(obj){
	now.setHours(0);
}
var x = 10;
document.write("渡す前の変数は" + x );
variable_pass(x);
document.write("、渡したあとの変数は" + x + "<br>");

var now = new Date();
document.write("渡す前の Date オブジェクトの時間要素は" + now.getHours());
object_pass(now);
document.write("、渡したあとの Date オブジェクトの時間要素は" + now.getHours());

書いてみたらすとんとわかったので、やっぱ書いてみるのって大事だなあ。

クロージャについて

JavaScript にはスタティック変数がない。スタティック変数とは宣言した関数の中でのみ使え、しかし関数が終了してもメモリから消えないもののこと。
今の自分にはいまいちこれのありがたみがわからない(グローバル変数じゃだめなの??って思ってしまう…)が、とにかく重要らしい。そのうちこれの重要さがわかるといいんだけど。
まあとにかく、クロージャというテクニックを用いるとこれと似たようなことが JavaScript でも実装できるらしい。
九章第五回 クロージャ — JavaScript初級者から中級者になろう — uhyohyo.net を読んで少しだけイメージが湧いたけど、どうやらこのクロージャを用いることによって変数の保護、されたくない動作の阻害などができるらしい。

function initCounter () {
	var count = 0;
	return function(){
		count ++;
		return count;
	};
}
var ct = initCounter();
document.write("ct = " + ct() + "<br>");
document.write("ct = " + ct() + "<br>");

これも書いてステップ実行したらやっていることがよくわかった。どういう時に使えるかは未だもやもやとしたイメージでしかないけど。
ct に initCounter() の値が入る時点では入るのはあくまで function() であり、count ではない。
ct() が実行されるときに初めて function() の中身が実行される。
これステップ実行しなかったらわからなかったなあ。

JavaScript 中級編の勉強を開始

JavaScript 中級編

さて、昨日までで基本のキの JavaScript の勉強を終えた。
今までちゃんとわかっていなかったタグとか CSS とかその辺りが理解できるようになったかな。
まあそれは JavaScript じゃなくて Html とか CSS だけど…。
今までどう書けばいいかは何となくわかっていて、でもどこで書けばいいのか、何ができるのかがいまいちちゃんとわかっていなかったけど、そのあたりが少しわかった気がする。
で、今日から中級編。
使うテキストはこちら。

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

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

前のテキストに比べるとようやく外で広げても恥ずかしくない感じ。
前のは正直言ってコンピュータ詳しくない人向けって感じでちょっとだけ恥ずかしかった…。
Amazon review で評価がよく、自分の目指すところ(= Chrome 拡張機能ブックマークレットが自在に書けるようになること)に近そうだったので、これに決めました。
結構分厚いけどその分面白いだろうと思うので、頑張って 1 日か 2 日ぐらいまでに終わらせられたらいいな。

突っかかったところ

Aptana Studio のプロジェクト一覧で大量のプロジェクトが並んでしまうのを避けたかったため、
/workspace/xxx/Chapter1
/workspace/xxx/Chapter2

といった階層構造にしたかったけれど、xxx というフォルダの中にプロジェクトを作成しようとしたところ、"overlaps the location of another project" と言われた。何とも conflict していない筈なんだけど。
ワークスペースを workspace/ から workspace/xxx/ にしたところ滞り無くできたけど、ワークスペースを変える必要が生じるっていうのがなんとなく腑に落ちない。
eclipse とかだと普通にプロジェクトのソースを階層構造で保管できたので、eclipse でできてこっちで出来ないというのはいったい何でだろう…と試行錯誤したところ、プロジェクトの中にフォルダは追加できた。ということで自分のやりたいことが間違っていたっぽい。
確かに考えてみたらその通りで、プロジェクトにフォルダは追加できてもその逆はおかしいよねえ。なんで最初それをやろうと思ったんだろう…。

学んだこと

XHTML と HTML は切っても切り離せない

Aptana Studio で HTML を書いていると、文の最後にスラッシュが挿入されてしまう。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

これは XHTML の記法で、HTML で書いているつもりの自分としては嫌だなー。どうにかしたいなー、と思っていた。
設定とか見てみても記法を HTML にするところが見つからないし、英語のフォーラムで同じような質問をしていた人はいたけど、「最初にファイルを作るときに XHTML 形式で作るのを選べばいいじゃん」って言われていた。でもそうすると blank file で作れないしなーっと思っていたら、
正しいHTMLを覚えよう~SEOバッチリなテンプレ使っても失敗するかもよ!|ぼくんちのバックステージ で「両者は区別が付けれない位ごっちゃになっている」と書かれていたのでちょっと気が楽になった。
なるべく正しく書きたいと思っていたけどあんまり気にしなくていいんだな。まだちょっともやもやは残るけど、まあ解決と言っていいかも。

XHTML での Script の書き方

上のとちょっと関連しているかも。知識の整理のために書いておく。
HTML では Script は CDATA の形式だったが、XHTML では #PCDATA の形式になっている。
#PCDATA の特徴はこちら。

  • HTML のコメント()は無視される。
  • 実体参照は文字に置き換えられる。
  • < はタグの開始文字として解釈される。

というわけで、HTML で書くように XHTMLJavaScript を書くと基本的には無視される。なので XHTML の形式に従って JavaScript を書くと

<script type = "text/javascript">
<![CDATA[
<!-- コード -->
]]>
</script>

となるが、頭のいいブラウザ達は HTML 形式に従った XHTML のコード上でも script が動くように解釈する結果、このような書き方だとエラーが起きるらしい…。
なので、こんな感じで書くといいらしい。

<script type = "text/javascript">
//<![CDATA[
<!-- コード -->
//]]>
</script>

ややこしいなー。

勉強の進捗

英語が少し聞き取れるようになったかな?

連結した言葉のリスニングが苦手ということが判明して、集中してそういった言葉ばかりを聞いた結果、自分でもわかるほどこういったものが少し聞き取れるようになった…気がした!これは嬉しい。
実際チェックテストみたいなものをしてみると、まだ全然聞き取れていないものが多いんだけど、聞き取れるようになったものもあるっぽい。
ただ、ここが聞き取れるようになった分、他の苦手箇所が目立ってきたかも。
チェックテスト、まだ全部終わっていないけど、「子音が連続する場合、前の子音が聞こえない」(beside me, could hear とか)の間違え方が半端ない。単に登場回数も多いのかもしれないけど。
チェックテストを全部終えて、苦手そうなところのフォローアップしたらまた少し良くなるといいんだけど。

JavaScript の基本の勉強が終わった

用意していた一冊目の超初級者向けのテキストは終了した。
JavaScript そのものより、CSS とか Html とかでわかっていないところが多数あったので、そのあたりの勉強にとても役に立った。
あとデバッグの練習とかにも良かったかな。
そんなに分厚くないテキストとはいえ、これを 2 日でやり遂げられたのは自分的にはとても大きい。
このまま中級者用の二冊目のテキストも頑張る!
目指すはブックマークレットとかを自由自在に作れること。

リスニングの弱点がわかった

リスニングの勉強でやり始めたこれが予想外によかった。

英語リスニングのお医者さん [改訂新版]

英語リスニングのお医者さん [改訂新版]

この本では日本人が苦手とするリスニングのタイプを幾つかに分け、それぞれに応じた練習をする形式になっている。
最初に読者がすることは自分の苦手なリスニングのタイプを知ること。というわけでチェックテストを受ける。
それがもう、この時点で目から鱗だった。
チェックテストの結果、自分はあからさまに音の連結が苦手だった。他の項目の 4-5 倍間違えている。
特に音の連結の中でも

  • 子音と母音がつながる(keep in touch とか)
  • 上の発展形で 3 語以上の音がつながる(come on in とか)

というのが全然聞けていなかった。これらに関する間違いがほかのものより段違いで多い。
正直ここまで差があるとは思わなくて、チェックテストを受けても「全体的に出来ないねー」みたいな結果に終わるのかな?と事前予想をしていたのでここまで明らかな結果でびっくりした。
また本に書いてあった

単語の一つ一つを聞き取ろうとするから、混乱するのです。

に衝撃を受けた。確かにその通り!自分は今まで単語一つ一つを聞き取ろうとしていた。

ナチュラルスピードで話される英語が聞き取りにくいのは、話すスピードが速くなって、前と後ろの単語の音がくっついて聞こえ、2つの語感の「間」がなくなってしまうからなのです。

続けて書かれていたこれも本当にそのとおりだと思う。でもわかっていても聞こえないわけで…。
しかしそれでも原因がわかった以上そこに焦点を当てた練習すれば格段に上達するはず!ということでここに集中して取り組んでみた。
そういった音ばかりが集められているセクションがあって、それをひたすら聞いて shadowing を行ってみた。そうすると、はじめたばかりの時より最後のほうがよりクリアに聞き取ることが出来た気がした。
気のせいかもしれないけど、勉強をしていく上で出来るようになったという実感が持てたことはとても大きい。
明日も頑張る。