ラベル Javascript の投稿を表示しています。 すべての投稿を表示
ラベル Javascript の投稿を表示しています。 すべての投稿を表示

2011年12月10日土曜日

Chromeのconsole.logの謎



この記事を読んで、Chromeのconsole.logの動きが謎すぎる気がして確認してみました。


CoffeeScriptで、newするときのプロパティ変数の初期化ってどーなってんの? - uzullaがブログ


検証


ソースコード


var a = [];

a.push('A');
console.log(a);

a.push('A');
console.log(a);


これをChromeのDeveloper toolのコンソールで実行してみました。


期待する出力


["A"]
["A", "A"]


実際の出力


["A", "A"]
["A", "A"]


調べてみた


console.log lazy等でググるとStackoverflow等のサイトがでてきた。


Is Chrome's JavaScript console lazy about evaluating arrays? - Stack Overflow


javascript - Bizarre console.log behaviour in Chrome Developer Tools - Stack Overflow


Bug 35801 – console.log object maps are read when you open the treeview on the console, not when they’re output in the console


なるほど。Webkit特有なのかもしれません。


console.logにオブジェクトを渡すと、console.logはそのオブジェクトの内容を出力します。


console.logが出力する準備をしている間にそのオブジェクトに変更を加えると変更後のオブジェクトの内容が出力されると。


シンプルな解決方法として




  • JSON.stringify

  • toString

  • slice (配列の場合)


等のメソッドや関数を使って別のオブジェクトを作成してから渡す方法が挙げられてますね。


ちなみに



Coffeescriptのクラスのプロパティ変数って、初期化が必須なの?(;´Д`)
コンストラクタで宣言しなおさないと、暗黙のウチに共有されちゃうの?
そういうもんなの??

JavaScriptのprototype継承ですね。



class Chain
queue: []
test: -> @queue.push "A"




var Chain;
Chain = (function() {
function Chain() {}
Chain.prototype.queue = [];
Chain.prototype.test = function() {
return this.queue.push("A");
};
return Chain;
})();


JavaScriptになるとこうなっています。


Chainクラスはprototypeというオブジェクトを持っています。(以下prototypeオブジェクト)


CoffeeScriptのクラスのメソッド等はこのprototypeオブジェクトのプロパティに定義されます。


Chainクラスのインスタンスはprototypeオブジェクトへの参照を持っています。


Chainクラスのインスタンスからqueueプロパティにアクセスするとき




  1. まずインスタンス自身がqueueプロパティを持っていないか調べる

  2. 持っていなければクラスのprototypeオブジェクトにqueueがないか調べる。

  3. クラスのprototypeオブジェクトにもqueueプロパティがなければ更に継承元のクラスを辿って行く


という感じになってます。


インスタンス自身がプロパティを持っているかどうか調べるためにはhasOwnPropertyを使います。



ソースコード



class Chain
queue: []
test: -> @queue.push "A"

c = new Chain
console.log "before c.queue = []"
console.log c.hasOwnProperty "queue"

c.queue = []

console.log "after c.queue = []"
console.log c.hasOwnProperty "queue"


実行結果


before c.queue = []
false
after c.queue = []
true


queueプロパティに配列を代入するまで、Chainクラスのインスタンスは自分自身のqueueプロパティを持ちません。


そのため、全てのインスタンスがChainクラスのprototypeオブジェクトのqueueプロパティを参照しています。


なのでtestメソッドの中でthis.queue.push("A")を呼び出すと、Chainクラスのprototypeオブジェクトのqueueプロパティが変更されるわけです。


こう書くとなおるわけ



ソースコード



class Chain
constructor: -> @queue = []

console.log "c = new Chain"
c = new Chain
console.log "c.hasOwnProperty 'queue': #{c.hasOwnProperty 'queue'}"


JavaScriptになると



var Chain, c;
Chain = (function() {
function Chain() {
this.queue = [];
}
return Chain;
})();

console.log("c = new Chain");
c = new Chain;
console.log("c.hasOwnProperty 'queue': " + (c.hasOwnProperty('queue')));


実行結果


c = new Chain
c.hasOwnProperty 'queue': true


コンストラクタの中で以下のコードを呼び出すことで、インスタンス自身のプロパティとしてqueueを定義しています。



this.queue = [];


インスタンス自身のプロパティなので、ほかのインスタンスのqueueを変更しても、関係ない。


そんな感じ。


まとめ




  • Webkitのconsole.logはオブジェクトが表示されるまでにディレイがあって、その途中でオブジェクトの中身を変更すると、変更後の内容が出力される

  • CoffeeScriptのクラスの仕組みについて知るためにはJavaScriptのプロトタイプチェーン等に関する知識が必要。


JavaScriptについて勉強するにはパーフェクトJavaScriptがお勧めです。



パーフェクトJavaScript (PERFECT SERIES 4)

パーフェクトJavaScript (PERFECT SERIES 4)










2011年12月5日月曜日

EmacsでJavaScriptの環境を整えたい



とりあえずここを参考にEmacsからChromeやNodeを叩けるようになりました。


Emacsからnode.jsやChromeとSocket通信 - 八発白中


ひっかかった点


swank-jsは更新されてるようで、本家のものを使うことでいけた。


僕の環境だと問題になったのはSLIME.


最新のSLIMEを使うと、slime-connectした際にcoding-systemが云々とエラーメッセージが出てうまく動かなかった。


昔のやつを落としてきて、うまく動いた。


js2-mode


js2-mode - 紫藤のWiki


ここを参考にしながら、Google Codeから最新版を落としてきて



% cp ~/Downloads/js2-20090723b.el ~/.emacs.d/elisp/js2.el
% emacs -batch -f batch-byte-compile ~/.emacs.d/elisp/js2.el

して、init.elに



(autoload 'js2-mode "js2" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))

を書き加えていけた。(~/.emacs.d/elisp/にパスを通してないとだめ)





2011年10月6日木曜日

ハッカソンの前にenchant.js環境構築



日本Androidの会 沖縄支部 workshop@Naha Vol.12 : ATND


来る10月15日にOJAGの勉強会があります。当日予定されているハッカソンに向けて開発環境を整えます。


ハッカソンで使用するのは以下なライブラリ(appMobiも使うのですが別エントリでまとめます)


no title


HTML5とJavaScriptで簡単にゲームが書けるゲームエンジン、様々なプラットフォームに対応しています。


環境構築


GitHub ? Social Coding


このページのDOWNLOAD PACKAGESのバージョンが一番新しい奴をダウンロードして展開します。


これで環境構築は完了です。(多分)


使いか方は多分、HTMLファイルの中のscriptタグでenchant.jsを読み込むだけ。


あとはゲームの処理を別のJavaScriptファイルに書いてそれを同じようにscriptタグで読み込ませます。


HTMLとJavaScriptを何で書くかはお好みですがうちの学生としてはvimを使え、となるのかな?


私はIDE使った方が楽だと思います。エラー表示とか出るし。EclipseかAptanaお勧めです。


ついでに9leapも登録する

9leap : トップページ - どこでも遊べる、投稿型ゲームサイト


enchant.jsを使って作られたゲームがたくさん投稿されてるので参考になるはず。


登録しなくてもソースは読めますが自分もコンテストに参加してみたいので登録しておきます。


Twitterのアカウントがあれば簡単に登録出来ます。




  1. 右上のログインを押す

  2. Twitterのアカウントでログインを済まし連携アプリを認証を押す


おそらくこれだけで完了です。あれ?自分前に登録したっけ? @taka16_O あたりに確認取ってもらおう。


ドキュメント


enchant


開発者の方によるスライドが分かりやすいです。


とりあえずこれを参考にざっくり概要を理解。


GitHub Pages ? File Not Found ? GitHub


実際書くときはリファレンスとしてここを参照するかと。


次のステップ


ひとまずenchant.jsをダウンロードして展開すれば環境構築は完了です。


日本Androidの会 沖縄支部 workshop@Naha Vol.12 : ATND


no title


などに掲載されているチュートリアルやサンプルをなぞって書いていく事になるかと。


来週の放課後当たりに時間が取れればいいなぁ。


# クリエイター科な学生の方は画像素材等も自分で作れそうですね、相談してみよう…





2010年6月7日月曜日

市松模様をcanvasで。



とりあえず書いてみた。
市松模様だけじゃつまらんなぁ。

市松模様

先日授業で市松模様を描くという内容の問題が出た。
考え方としては幾つかある気がするが、いつもの癖でショートコーディングしてると結局1行でかけた。
思ってることを日本語でうまく書き出せないのでとりあえずコードだけ貼っておくことにする。