javascript勉強会
DESCRIPTION
社内で行ったJavaScript勉強会の資料。TRANSCRIPT
JavaScriptJavaScriptJavaScriptJavaScriptJavaScriptJavaScriptJavaScriptJavaScript 再入門再入門再入門再入門再入門再入門再入門再入門
2008/052008/052008/052008/052008/052008/052008/052008/05////////2020202020202020
matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]matsukaz [http://d.hatena.ne.jp/matsukaz/]
アジェンダ
1. JavaScript概要
2. JavaScriptのオブジェクト
3. 連想配列
4. プロトタイプ
5. 継承
6. クロージャ
7. 参考サイト
1. JavaScript概要
• JavaScriptとは
• JavaScriptとECMAScript
• ECMAScript実装
• ECMAScript関係図
JavaScriptとは
• プロトタイプベースのオブジェクト指向なスクリプト言語
• Netscapeによって開発された
• 開発当初はLiveScriptだったが、Javaの話題性に便乗してJavaScriptという名称に
–言語仕様は似ているがJavaとは関係ない
• Microsoftの実装はJavaScriptに自社技術を追加して拡張したJScript
1. JavaScript1. JavaScript1. JavaScript1. JavaScript概要概要概要概要
JavaScriptとECMAScript
• Ecma Internationalによって策定
• 互換性の低かったJavaScriptとJScriptの標準化を目的に作られたスクリプト言語
–式や構文、基本オブジェクトなどの仕様を決めている
–ブラウザ固有の機能は含められていない
1. JavaScript1. JavaScript1. JavaScript1. JavaScript概要概要概要概要
ブラウザ別ECMAScript実装
ECMAScript 4に等価JavaScript 2.0-
ECMAScript 3に機能追加-Safari
ECMAScript 3に機能追加-Opera 9
JavaScript 1.8に機能追加予定JavaScript 1.9Firefox (次バージョン)
JavaScript 1.7に機能追加JavaScript 1.8Firefox 3.0
JavaScript 1.6に機能追加JavaScript 1.7Firefox 2.0
JavaScript 1.5に機能追加JavaScript 1.6Firefox 1.5
ECMAScript 3に等価JavaScript 1.5Firefox 1.0
ECMAScript 3/Javascript 1.5に等価(JScript 5のバグFix)
JScript 6IE8
ECMAScript 3/Javascript 1.5に等価JScript 5IE6-7
説明名称ブラウザ
出展元:Versions of Javascript((((http://ejohn.org/blog/versions-of-javascript/))))
マイコミジャーナルの記事(マイコミジャーナルの記事(マイコミジャーナルの記事(マイコミジャーナルの記事(http://journal.mycom.co.jp/news/2008/04/25/021/))))
1. JavaScript1. JavaScript1. JavaScript1. JavaScript概要概要概要概要
ECMAScriptECMAScriptECMAScriptECMAScript関係図関係図関係図関係図
出展元:The World of ECMAScript ((((http://ejohn.org/blog/the-world-of-ecmascript/))))
1. JavaScript1. JavaScript1. JavaScript1. JavaScript概要概要概要概要
2. JavaScriptのオブジェクト
• オブジェクトの構成
• 関数
• 高階関数
• コンストラクタ関数
オブジェクトの構成
• JavaScriptのオブジェクトはプロパティのみを持つ
• プロパティにセットできる値もオブジェクト
• 各オブジェクトには自由にプロパティを追加/削除できる
var hogeObj = new Object();
var fugaObj = new Object();
fugaObj.foo = 'fooVal'; // foo プロパティに 'fooVal' をセットhogeObj.fuga = fugaObj; // fuga プロパティに fugaObj をセット
alert(hogeObj.fuga.foo); // 'fooVal' と表示
var hogeObj = new Object();
var fugaObj = new Object();
fugaObj.foo = 'fooVal'; // foo プロパティに 'fooVal' をセットhogeObj.fuga = fugaObj; // fuga プロパティに fugaObj をセット
alert(hogeObj.fuga.foo); // 'fooVal' と表示
2. JavaScript2. JavaScript2. JavaScript2. JavaScriptのオブジェクトのオブジェクトのオブジェクトのオブジェクト
関数
• JavaScriptでは関数もオブジェクト
–プロパティに関数をセットしたものがメソッドとなる
var hogeObj = new Object();
var fugaFunc = function(val){ // 関数を変数として定義alert(val);
}
hogeObj.fuga = fugaFunc; // fuga プロパティに関数をセットhogeObj.fuga('fugaVal'); // 'fugaVal' と表示
var hogeObj = new Object();
var fugaFunc = function(val){ // 関数を変数として定義alert(val);
}
hogeObj.fuga = fugaFunc; // fuga プロパティに関数をセットhogeObj.fuga('fugaVal'); // 'fugaVal' と表示
2. JavaScript2. JavaScript2. JavaScript2. JavaScriptのオブジェクトのオブジェクトのオブジェクトのオブジェクト
高階関数
• 引数に関数を受け取る関数
function hoge(val){ // 関数を定義alert('hello, ' + val);
}
function fuga(array, fn) { // 高階関数for (var i = 0;i < array.length; i++) {
fn(array[i]);
}
}
var array = ['foo', 'bar']; // 配列を定義fuga(array, hoge); // 'hello, foo' 、'hello, bar' と表示
function hoge(val){ // 関数を定義alert('hello, ' + val);
}
function fuga(array, fn) { // 高階関数for (var i = 0;i < array.length; i++) {
fn(array[i]);
}
}
var array = ['foo', 'bar']; // 配列を定義fuga(array, hoge); // 'hello, foo' 、'hello, bar' と表示
2. JavaScript2. JavaScript2. JavaScript2. JavaScriptのオブジェクトのオブジェクトのオブジェクトのオブジェクト
コンストラクタ関数
• コンストラクタ関数でオブジェクトの種類を定義
–全ての関数はコンストラクタ関数となりえる
function Hoge(val){ // コンストラクタ関数this.val = val; // this はこれから生成されるオブジェクトthis.message = function(){ // 無名関数alert(this.val);
}
}
var hogeObj = new Hoge('fugaVal'); // new で Hoge オブジェクトを生成hogeObj.message(); // 'fugaVal' と表示
function Hoge(val){ // コンストラクタ関数this.val = val; // this はこれから生成されるオブジェクトthis.message = function(){ // 無名関数alert(this.val);
}
}
var hogeObj = new Hoge('fugaVal'); // new で Hoge オブジェクトを生成hogeObj.message(); // 'fugaVal' と表示
2. JavaScript2. JavaScript2. JavaScript2. JavaScriptのオブジェクトのオブジェクトのオブジェクトのオブジェクト
3. 連想配列
• 連想配列とは
• オブジェクトと連想配列
連想配列とは
• 配列
–添え字に整数を利用
var array = ['hogeVal', 'fugaVal'];
alert(array[0]); // 'hogeVal' と表示alert(array[1]); // 'fugaVal' と表示
var array = ['hogeVal', 'fugaVal'];
alert(array[0]); // 'hogeVal' と表示alert(array[1]); // 'fugaVal' と表示
• 連想配列
–添え字に文字列を利用
• JavaにおけるHashtableと同じ
var hash = {'hogeKey' : 'hogeVal', 'fugaKey' : 'fugaVal'};
alert(hash['hogeKey']); // 'hogeVal' と表示alert(hash['fugaKey']); // 'fugaVal' と表示
var hash = {'hogeKey' : 'hogeVal', 'fugaKey' : 'fugaVal'};
alert(hash['hogeKey']); // 'hogeVal' と表示alert(hash['fugaKey']); // 'fugaVal' と表示
3. 3. 3. 3. 連想配列連想配列連想配列連想配列
オブジェクトと連想配列
• 全てのオブジェクトは連想配列
–下記オブジェクトは全て同じプロパティを持つ
var obj1 = new Object();
obj1.hogeKey = 'hogeVal'; // 空オブジェクトにプロパティを追加
var obj2 = {'hogeKey' : 'hogeVal'}; // 連想配列を定義
var obj3 = {hogeKey : 'hogeVal'}; // 連想配列を定義(キーは '' で囲まなくても良い)
var obj4 = {};
obj4['hogeKey'] = 'hogeVal'; // 空の連想配列にキーを追加
var obj1 = new Object();
obj1.hogeKey = 'hogeVal'; // 空オブジェクトにプロパティを追加
var obj2 = {'hogeKey' : 'hogeVal'}; // 連想配列を定義
var obj3 = {hogeKey : 'hogeVal'}; // 連想配列を定義(キーは '' で囲まなくても良い)
var obj4 = {};
obj4['hogeKey'] = 'hogeVal'; // 空の連想配列にキーを追加
– こんな指定も可能
var val1 = document.location.protocol;
var val2 = document['location']['protocol']; // プロパティを連想配列のキーで指定
var val1 = document.location.protocol;
var val2 = document['location']['protocol']; // プロパティを連想配列のキーで指定
3. 3. 3. 3. 連想配列連想配列連想配列連想配列
• 呼び出すプロパティを動的変更できるということ
4. プロトタイプ
• prototypeオブジェクト
• 暗黙の参照
• プロトタイプチェーン
• 定義済みオブジェクトの拡張
prototypeプロパティ
• 全ての関数オブジェクトは、prototypeプロパティを保持している
function Hoge(){}
alert(Hoge.prototype != undefined); // trueと表示
function Hoge(){}
alert(Hoge.prototype != undefined); // trueと表示
• prototypeプロパティのデフォルトの参照先は空のオブジェクト
4. 4. 4. 4. プロトタイププロトタイププロトタイププロトタイプ
Hoge.prototype.fuga = 'FugaVal'; // prototypeプロパティの参照先のオブジェクトに// プロパティを設定可能
Hoge.prototype.fuga = 'FugaVal'; // prototypeプロパティの参照先のオブジェクトに// プロパティを設定可能
暗黙の参照
Hoge
fuga = 10
function Hoge(){}
Hoge.prototype.fuga =10;
function Hoge(){}
Hoge.prototype.fuga =10;
var hogeObj1 = new Hoge();
hogeObj1.fuga = 20;
var hogeObj1 = new Hoge();
hogeObj1.fuga = 20;
alert(hogeObj1.fuga); // 20 と表示alert(hogeObj2.fuga); // 10 と表示
alert(hogeObj1.fuga); // 20 と表示alert(hogeObj2.fuga); // 10 と表示
var hogeObj2 = new Hoge();var hogeObj2 = new Hoge();
• オブジェクトが指定したプロパティを持たない場合、そのオブジェクトは生成元のコンストラクタ関数のprototypeプロパティへ暗黙の参照を持つ
4. 4. 4. 4. プロトタイププロトタイププロトタイププロトタイプ
hogeObj1
fuga = 20
hogeObj2
プロトタイプチェーン
• プロトタイプを連鎖させることもできる
Hoge
fuga = 10
var hogeObj = new Hoge();var hogeObj = new Hoge();
alert(fooObj.hoge.fuga); // 10 と表示alert(fooObj.hoge.fuga); // 10 と表示
Foo
hoge = hogeObj
function Hoge(){}
Hoge.prototype.fuga = 10;
function Hoge(){}
Hoge.prototype.fuga = 10;
function Foo(){}
Foo.prototype.hoge = hogeObj;
function Foo(){}
Foo.prototype.hoge = hogeObj;
var fooObj = new Foo();var fooObj = new Foo();
4. 4. 4. 4. プロトタイププロトタイププロトタイププロトタイプ
hogeObj
fooObj
定義済みオブジェクトの拡張
• 定義済みオブジェクトを拡張することもできる
Object.prototype.hoge = 'hogeVal';
var obj = new Object();
alert(obj.hoge); // 'hogeVal' と表示
Object.prototype.hoge = 'hogeVal';
var obj = new Object();
alert(obj.hoge); // 'hogeVal' と表示
Date.prototype.toJPString = function(){
return this.getFullYear() + '年' + (this.getMonth() + 1)
+ '月' + this.getDate() + '日';
}
var date = new Date();
alert(date.toJPString()); // '2008年5月20日' と表示
Date.prototype.toJPString = function(){
return this.getFullYear() + '年' + (this.getMonth() + 1)
+ '月' + this.getDate() + '日';
}
var date = new Date();
alert(date.toJPString()); // '2008年5月20日' と表示
4. 4. 4. 4. プロトタイププロトタイププロトタイププロトタイプ
5. 継承
• 継承とは
• 継承の実装方法
• constructorプロパティ
継承とは
• 継承元で定義された機能を受け継いで、自分自身の機能を追加可能とする仕組み
var person = new Person();
person.getName(); // Person の関数
var person = new Person();
person.getName(); // Person の関数
var emp = new Employee();
emp.getName(); // Person の関数emp.getDept(); // Employee の関数
var emp = new Employee();
emp.getName(); // Person の関数emp.getDept(); // Employee の関数
Person
getName()
Employee
getDept()
5. 5. 5. 5. 継承継承継承継承
継承の実装方法
• JavaScriptとして継承という機能は提供されていない
– JavaScript 2.0(ECMAScript 4)でサポート予定
• プロトタイプチェーンを繋いでいくことで継承らしき実装を実現
– さまざまなパターンの実装方法が存在
• オブジェクトの代入
• プロパティのコピー
• prototypeの代入
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(オブジェクトの代入)
• 継承元のオブジェクトを継承先のprototypeに代入する
function Person(name){this.name = name;}
Person.prototype.getName = function(){return this.name;}
function Person(name){this.name = name;}
Person.prototype.getName = function(){return this.name;}
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.prototype = new Person; // 継承元のオブジェクトを// prototype プロパティに代入
Employee.prototype.getDept = function(){return this.dept;}
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.prototype = new Person; // 継承元のオブジェクトを// prototype プロパティに代入
Employee.prototype.getDept = function(){return this.dept;}
Mozillaやオライリーではこの方法を紹介している。でもオブジェクトを作る目的以外でnewするってどうなの?引数が必須の場合は何を渡
す?コンストラクタ関数内で何らかの処理をしていたら?いろいろ問題が・・・
Mozillaやオライリーではこの方法を紹介している。でもオブジェクトを作る目的以外でnewするってどうなの?引数が必須の場合は何を渡
す?コンストラクタ関数内で何らかの処理をしていたら?いろいろ問題が・・・
Person
getName()
Employee
getDept()
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(オブジェクトの代入)
• 概念図
参照
new
無名オブジェクト
暗黙の参照
new
emp
暗黙の参照
Person
prototype
Employee
prototype
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(プロパティのコピー)
• 継承元のprototypeのプロパティを継承先にコピーする
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.inherit(Person);
Employee.prototype.getDept = function(){return this.dept;}
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.inherit(Person);
Employee.prototype.getDept = function(){return this.dept;}
// 継承元の prototype プロパティを継承先にコピーする関数Function.prototype.inherit = function(superClass){
for(var prop in superClass.prototype){
this.prototype[prop] = superClass.prototype[prop];
}
}
// 継承元の prototype プロパティを継承先にコピーする関数Function.prototype.inherit = function(superClass){
for(var prop in superClass.prototype){
this.prototype[prop] = superClass.prototype[prop];
}
}
個別にプロパティをセットしているので、あとから継承元のprototypeにプロパティを追加
しても反映されない・・・
個別にプロパティをセットしているので、あとから継承元のprototypeにプロパティを追加
しても反映されない・・・
Person
getName()
Employee
getDept()
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(プロパティのコピー)
• 概念図
プロパティのコピー
new
emp
暗黙の参照
Person
prototype
Employee
prototype
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(プロトタイプの代入)
• 継承元のprototypeをオブジェクト化して継承先のprototypeに代入する
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.inherit(Person);
Employee.prototype.getDept = function(){return this.dept;}
function Employee(name, dept){
Person.call(this, name); // 親のコンストラクタ関数呼び出しthis.dept = dept;
}
Employee.inherit(Person);
Employee.prototype.getDept = function(){return this.dept;}
// 継承元の prototype プロパティを継承先の prototype に代入Function.prototype.inherit(superClass){
function Temp(){}
Temp.prototype = superClass.prototype;
this.prototype = new Temp;
}
// 継承元の prototype プロパティを継承先の prototype に代入Function.prototype.inherit(superClass){
function Temp(){}
Temp.prototype = superClass.prototype;
this.prototype = new Temp;
}
一番継承っぽい。あとから継承元のprototypeにプロパティを追加しても反映される。
一番継承っぽい。あとから継承元のprototypeにプロパティを追加しても反映される。
Person
getName()
Employee
getDept()
5. 5. 5. 5. 継承継承継承継承
継承の実装方法(プロトタイプの代入)
• 概念図
new
無名オブジェクト
参照
Person
prototype
Employee
prototype
Temp
prototype参照
暗黙の参照
5. 5. 5. 5. 継承継承継承継承
constructorプロパティ
• オブジェクト名.constructor
–生成元コンストラクタ関数を参照
function Person(name){this.name = name;}
var hoge = new Person('hoge');
alert(hoge.constructor); // Person関数の内容を表示alert(hoge.constructor.name); // Personと表示
function Person(name){this.name = name;}
var hoge = new Person('hoge');
alert(hoge.constructor); // Person関数の内容を表示alert(hoge.constructor.name); // Personと表示
※ constructorのnameプロパティにはIEからはアクセスできない
• 継承の実装次第では、生成元コンストラクタ関数が異なってしまう
–明示的にconstructorプロパティを設定する
Employee.prototype.constructor = Employee;Employee.prototype.constructor = Employee;
5. 5. 5. 5. 継承継承継承継承
6. クロージャ
• クロージャとは
• クロージャの特徴
• クロージャの利用例
• クロージャ利用時の注意点
クロージャとは
• 関数の中で定義された関数
function Hoge(){
this.fuga = function(msg){ // クロージャalert(msg);
}
}
var hogeObj = new Hoge();
hogeObj.fuga('hogeVal'); // 'hogeVal' と表示
function Hoge(){
this.fuga = function(msg){ // クロージャalert(msg);
}
}
var hogeObj = new Hoge();
hogeObj.fuga('hogeVal'); // 'hogeVal' と表示
function hoge(){
function fuga(msg){ // クロージャalert(msg);
}
return fuga;
}
var fugaFunc = hoge();
fugaFunc('fugaVal'); // 'fugaVal' と表示
function hoge(){
function fuga(msg){ // クロージャalert(msg);
}
return fuga;
}
var fugaFunc = hoge();
fugaFunc('fugaVal'); // 'fugaVal' と表示
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャの特徴
• 関数と、その関数が作られた環境が一体となった特殊なオブジェクト
• 関数の外側で宣言された変数に対する参照を持つ
function Hoge(msg){
var count = 1;
this.fuga = function(){ // クロージャalert(count + ', ' + msg); // count や msg に対する参照を持つcount++;
}
}
var hogeObj = new Hoge('hogeVal');
hogeObj.fuga(); // '1, hogeVal' と表示hogeObj.fuga(); // '2, hogeVal' と表示
function Hoge(msg){
var count = 1;
this.fuga = function(){ // クロージャalert(count + ', ' + msg); // count や msg に対する参照を持つcount++;
}
}
var hogeObj = new Hoge('hogeVal');
hogeObj.fuga(); // '1, hogeVal' と表示hogeObj.fuga(); // '2, hogeVal' と表示
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャの利用例①
• プライベート関数
–特定のスコープのみで実行可能な関数
• オブジェクト毎に関数オブジェクトが生成されるので、リソースには注意が必要
function Hoge(){
this.fuga = function(){
foo();
}
function foo(){ // クロージャ(プライベート関数)alert('foo');
}
}
var hoge = new Hoge();
hoge.fuga(); // 'foo' と表示
function Hoge(){
this.fuga = function(){
foo();
}
function foo(){ // クロージャ(プライベート関数)alert('foo');
}
}
var hoge = new Hoge();
hoge.fuga(); // 'foo' と表示
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャの利用例②
• イベント登録
– 各ボタン用のイベントを生成
<form name="form1">
<input type="text" name="text1">
<input type="button" name="button1" value="button1"><br>
<input type="text" name="text2">
<input type="button" name="button2" value="button2">
</form>
選択した値:<span id="disp"></span>
<form name="form1">
<input type="text" name="text1">
<input type="button" name="button1" value="button1"><br>
<input type="text" name="text2">
<input type="button" name="button2" value="button2">
</form>
選択した値:<span id="disp"></span>
document.form1.button1.onclick = dispValue('text1');
document.form1.button2.onclick = dispValue('text2');
function dispValue(target){
return function(){ // 各ボタン用のクロージャを作成disp.innerHTML = document.form1[target].value;
}
}
document.form1.button1.onclick = dispValue('text1');
document.form1.button2.onclick = dispValue('text2');
function dispValue(target){
return function(){ // 各ボタン用のクロージャを作成disp.innerHTML = document.form1[target].value;
}
}
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャ利用時の注意点
• ループ内でクロージャを作成
–ループ内のクロージャは、関数としては異なるが同じ環境を共有しているため、keyは同じ値になってしまう。
var map = {
'button1' : 'text1',
'button2' : 'text2'
};
for(var key in map){
document.form1[key].onclick = function(){ // ループ内のクロージャdisp.innerHTML = document.form1[map[key]].value; // keyの値に注意が必要
}
}
var map = {
'button1' : 'text1',
'button2' : 'text2'
};
for(var key in map){
document.form1[key].onclick = function(){ // ループ内のクロージャdisp.innerHTML = document.form1[map[key]].value; // keyの値に注意が必要
}
}
ポイントはどうやって共有する環境を切り離すか
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャ利用時の注意点
• 解決策①(イベント登録を関数で切り離す)
for(var key in map){
(function(n){ // 無名関数内でイベント登録を行うdocument.form1[key].onclick = function(){
disp.innerHTML = document.form1[n].value;
};
})(map[key]);
}
for(var key in map){
(function(n){ // 無名関数内でイベント登録を行うdocument.form1[key].onclick = function(){
disp.innerHTML = document.form1[n].value;
};
})(map[key]);
}
• 解決策②(イベント処理を関数で切り離す)
for(var key in map){
document.form1[key].onclick = (function(n){ // 無名関数内でイベント処理を行うreturn function(){
disp.innerHTML = document.form1[n].value;
}
})(map[key]);
}
for(var key in map){
document.form1[key].onclick = (function(n){ // 無名関数内でイベント処理を行うreturn function(){
disp.innerHTML = document.form1[n].value;
}
})(map[key]);
}
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
クロージャ利用時の注意点
• 解決策③(外部関数化する)
for(var key in map){
document.form1[key].onclick = dispValue(map[key]);
}
// 外部関数で生成した無名関数内でイベント処理を行うfunction dispValue(target){
return function(){ // 各ボタン用のクロージャを作成disp.innerHTML = document.form1[target].value;
}
}
for(var key in map){
document.form1[key].onclick = dispValue(map[key]);
}
// 外部関数で生成した無名関数内でイベント処理を行うfunction dispValue(target){
return function(){ // 各ボタン用のクロージャを作成disp.innerHTML = document.form1[target].value;
}
}
6. 6. 6. 6. クロージャクロージャクロージャクロージャ
7. 参考サイト
• Mozilla Developer Center– http://developer.mozilla.org/ja/docs/JavaScr
ipt
• ECMAScript– http://www.ecmascript.org/
• JavaScript Shell 1.4– http://www.squarefree.com/shell/shell.html
• CodeZineの記事– http://codezine.jp/a/article/aid/220.aspx
• 檜山正幸のキマイラ飼育記– http://d.hatena.ne.jp/m-hiyama/
べつやくメソッド的に言うと・・・
べつやくメソッド用べつやくメソッド用べつやくメソッド用べつやくメソッド用 円グラフ作成君(円グラフ作成君(円グラフ作成君(円グラフ作成君(http://818nc.jp/circle/))))