TODO
- javaのアクセス指定子の勉強
- js.jarのjnlpの指定方法
- js.jarのmavenの指定方法
基礎
javascriptの型
-
プリミティブ系
-
number
--string
--boolean
-オブジェクト系
--object
---Number
---String
---Boolean
---Array
---[]- null
-
function
-
number
未定義オブジェクト
未定義オブジェクトかどうかを判定するには以下の方法がある。
// 以下は全部同義(undefined, !, null) var hoge; if (hoge == undefined) { alert("未定義(undefined)"); } if (!hoge) { alert("未定義(!hoge)"); } if (hoge==null) { alert("未定義(null)"); }
連想配列の未定義のチェック
var hoges = new Array(); var hoge = hoges["hoge"]; if (hoge == undefined) { document.write("未定義"); }
数値かどうかのチェック
if(!isNaN(value)){ document.write("数字"); }
空のオブジェクト
var Object = {};
配列とハッシュ
var hash = {'java':0, 'script':1}; var array = ['java', 'script'];
すべてはハッシュ
var hello = {}; hello.world = function() { return "hello, world!" }; hello.hoge = 'hoge'; alert(hello.hoge); alert(hello['hoge']); alert(hello.world()); alert(hello['world']());
JavaScriptにおけるメンバの定義
var obj = new Object(); alert(obj.field); // 未定義。未定義の場合 undefined と評価される。 obj.field = 10; // 代入により field というメンバが定義された。 alert(obj.field); // 10 と評価される。
JavaScriptにおけるメンバの削除
var obj = new Object(); obj.field = 10; alert(obj.field); // 10 と評価される。 delete obj.field; // delete 演算子により fieldプロパティが削除される。 alert(obj.field); // 削除され未定義となったため undefined となる。
for in
連想配列からキーを取得できる
var info = new Array(); info["name"] = "hoge"; info["type"] = "cat"; info[0] = "A"; info[1] = "B"; for( key in info ){ alert( key + ":" + info[key]); }
for in でオブジェクトのプロパティを列挙できる
var obj = new Object(); obj.foo = 'value1'; obj.bar = 'value2' for (var key in obj) { alert(key + ":" + obj[key]); // keyにハッシュのキーが入る(プロパティ名) }
可変引数
argumentsオブジェクトを使うことにより動的にアクセス可能
function hoge(arg1, arg2) { alert(arg1 == arguments[0]); // true alert(arguments[3]); // 4 } hoge(1, 2, 3, 4);
コンストラクタ
// コンストラクタとは関数定義のこと。 var Hoge = function(){}; // だからこれもコンストラクタ。 function Hoge(){}; // で、これをnewしたらHogeオブジェクトのできあがり var hoge = new Hoge(); // フィールドを定義したい場合は以下のようにthisをつけて代入すればよい var Hoge = function(){ this.field1 = 0; this.field2 = 'hoge'; };
プロトタイプとは?
-
プロトタイプとはjavaでいうインスタンス。
-プロトタイプベースオブジェクト指向とはつまりインスタンスベースクラス指向のこと。
-javaのようにクラスの雛形をもとに静的にクラスを生成するのではなく、インスタンスをベースにクラスを量産するというイメージ。
**プロトタイプの仕組み(プロトタイプチェーン)
- コンストラクトした時点では、prototypeは通常、ただの空オブジェクト。
- まずオブジェクト自身のプロパティから、該当のプロパティ名を探索
- なかった場合、オブジェクトのprototypeオブジェクトのプロパティの中から該当する名前のプロパティを探す。
- それでもなければ、そのプロトタイプオブジェクトのprototypeから探索する。
- 最終的になにもプロパティを持たないprototypeになるまでこれを繰り返す。
- 見つからなければ、そこで代入になる。参照だったらundefinedのエラーになる
-
これがプロトタイプチェーン。
クラス定義
this,prototypeに定義したメンバは、newしないと参照できない。
定義した変数に直接メンバを設定するとクラス変数、クラスメソッドとなる。
var Hoge = function() { this.thisField = 10; this.thisMethod = function() { return 'hoge'; }; }; Hoge.prototype.protoMethod = function() { return 'hogehoge'; }; Hoge.prototype.protoField = 20; Hoge.FIELD = 30; // クラス変数 Hoge.METHOD = function() { return 'hogehogehoge'; }; // クラスメソッド var hoge = new Hoge(); // prototypeとthisはnewしないと参照できない alert('hoge.thisMethod():'+hoge.thisMethod()); // => 'hoge' alert('hoge.protoMethod():'+hoge.protoMethod()); // => 'hogehoge' //alert('hoge.METHOD():'+hoge.METHOD()); // => エラー not a function alert('hoge.thisField:'+hoge.thisField); // => 10 alert('hoge.protoField:'+hoge.protoField); // => 20 //alert('Hoge.thisMethod():'+Hoge.thisMethod()); // => エラー not a function //alert('Hoge.protoMethod():'+Hoge.protoMethod()); // => 同上 alert('Hoge.FIELD:'+Hoge.FIELD); // => 30 alert('Hoge.METHOD():'+Hoge.METHOD()); // => hogehogehoge
クラス継承
prototypeにスーパクラスのインスタンスを設定すればよい。
// スーパクラス var Hoge = function() { this.thisField = 10; this.thisMethod = function() { return 'hoge'; }; }; Hoge.prototype.protoMethod = function() { return 'hoge'; }; Hoge.prototype.protoField = 10; Hoge.FIELD = 10; // クラス変数 Hoge.METHOD = function() { return 'hoge'; }; // クラスメソッド // 継承クラス var Fuga = function() {}; // これでFugaのプロトタイプがHogeになる。つまり継承したことになる
Fuga.prototype = new Hoge(); var fuga = new Fuga(); alert('fuga.thisMethod():'+fuga.thisMethod()); // => 'hoge' alert('fuga.thisField:'+fuga.thisField); // => 10 alert('fuga.protoMethod():'+fuga.protoMethod()); // => 'hoge' alert('fuga.protoField:'+fuga.protoField); // => 10 // クラス変数へはアクセスできない alert('Fuga.FIELD:'+Fuga.FIELD); // => undefined fuga.thisField = 20; alert('fuga.thisField:'+fuga.thisField); // => 20 書き換わる fuga.protoField = 20; alert('fuga.protoField:'+fuga.protoField); // => 20 書き換わる fuga.thisMethod = function() { return 'fuga'; }; alert('fuga.thisMethod():'+fuga.thisMethod()); // => 'fuga' 書き換わる fuga.protoMethod = function() { return 'fuga'; }; alert('fuga.protoMethod():'+fuga.protoMethod()); // => 'fuga' 書き換わる // コンストラクタで上書きしたらどうなるか? // てかこれが本来の継承 var Piyo = function() { this.thisField = 20; this.thisMethod = function() { return 'piyo'; }; }; Piyo.prototype = new Hoge(); var piyo = new Piyo(); alert('piyo.thisMethod():'+piyo.thisMethod()); // => 'piyo' 書き換わる alert('piyo.thisField:'+piyo.thisField); // => 20 書き換わる
関数について
関数内のthisはグローバルオブジェクトのプロパティを示す。
function add(x, y) { this.result = x + y; // これはグローバルのresultを示す。 } add(2, 5); alert(result);
NullとUndefined
未定義変数
alert(sValue); // sValueが前もって宣言されていないため、エラーとなる → sValue is not defined
null変数
var sValue; alert(sValue); // エラーは起こらないが、undefinedと表示される
配列
-
配列
var hoge = []; // var hoge = new Array(); とも記述できる。 var hoge2 = [1,2,3,4]; var hoge3 = [1.1, true, "a"]; // ひとつの配列にどんな型も入れられる。
-
push, pop
var hoges = new Array(); hoges.push(0); // 配列の最後に追加 hoges.push(1); hoges.push(2); while (hoges.length != 0) { // 配列の最後を取り出す alert(hoges.pop()); // 2, 1, 0 の順番で表示 }
-
unsift, shift
var hoges = new Array(); hoges.unshift(0); // 配列の最初に追加 hoges.unshift(1); hoges.unshift(2); while (hoges.length != 0) { // 配列の最初を取り出す alert(hoges.shift()); // 2, 1, 0 の順番で表示 }
関数
- 関数宣言はコードの実行より前に解釈される。
-
c言語で言うstatic変数を関数内にもつ方法
uniqueInteger.counter = 0; // 関数自身にプロパティを設定する。 function uniqueInteger() { return uniqueInteger.counter++; // このプロパティは保持される。 }
apply()メソッドとcall()メソッド
f.call(o, 1, 2);
これは次のように記述したのと同じ
o.m = f; o.m(1,2); delete o.m;
applyは引数部分を配列で渡す。
f.apply(o, [1,2]);
演算子
基本型をチェックする(typeof)
// number, string , boolean , object, function のいずれかを返す var hoge = (typeof value == "string"? "moji": "sonota";
オブジェクトの型をチェックする
var d = new Date(); d instanceof Date; // true d inscanceof Object; // true d inscanceof Number; // false
等値演算子と同値演算子
- == は型変換してできるだけ等しくなるようにする。
- === は型が違えばその時点で、偽になる。
- ※== が浅い比較、===が深い比較ではないので注意
-
オブジェクト同士の比較
- ==でも===でも、同じ参照をさしている場合のみ、等しいと判断される。
- 同じプロパティ、同じ要素を刺して言うことを判定するには個別にチェックしなくてはならない。
-
nullとundefined
- ==では、nullもundefindeもnull(false)と判定されるが、===ではより厳密になるため、両者は区別される。
thisとprototypeどっちで定義すればよいか?
-
this
--プロパティが上書きできてしまうので好ましくない- インスタンスごとにメソッドを定義するのでメモリ効率がよくない
-
prototype
--prototyepのプロパティはそれを介したインスタンスで共通に参照される- したがってメモリ効率がよい
- とくにメソッドはprototypeに定義したほうがよい。
var Class = function(){ this.hoge = 0; this.fuga = function() { alert('fuga'); }; }; // var Class = function(){ this.hoge = 0; this.prototype.fuga = function() { alert('fuga'); }; };
参考リンク
非常に参考になる
読み物系
-
javascriptを理解するためのたった2つの大切なこと
--http://anond.hatelabo.jp/20070620200618
--http://anond.hatelabo.jp/20070622101313
-四則演算を JavaScript で実装する
--http://d.hatena.ne.jp/nitoyon/20070629/four_operations_implementation_in_javascript
-JavaScript: 世界で最も誤解されたプログラミング言語
--http://d.hatena.ne.jp/brazil/20050829/1125321936
-私は如何にしてJavascriptのprototypeを身につけたか。
--http://blog.xole.net/article.php?id=560
-かつてサーバーサイドJavaScriptは実在した
--http://neta.ywcafe.net/000573.html
-Rhino on Rails
--http://www.aoky.net/articles/steve_yegge/rhino-on-rails.htm