操作方法

PHPer向け
JavaScript入門

2008/08/29.
WEBシステムグループ第八技術チーム
嶋崎 聖

アジェンダ

JavaScriptで何ができるか

JavaScriptで何ができるか

JavaScriptの歴史

JavaScriptの歴史

Netscape社が自社のブラウザで動作するLiveScriptを開発


Sunと提携したこともあり、JavaScriptと改名する


JavaScript誕生


Microsoftが真似てJScriptを開発


お前ら紛らわしいから統一しる!


情報通信の標準化団体ECMA(エクマ/イーシーエムエー)が標準化を図る目的でECMAScript(ECMA-262)と呼ばれる規格を発表


現在の最新バージョンは3


注意:
ECMAScriptとJavaScript、及びJScriptは相変わらず別物は別物です。

なので
ブラウザの違いによる動作の違いに注意

言語としてのJavaScript

言語としてのJavaScript

JavaScriptの基本構文

JavaScriptの基本構文

基本はPHPと同じ

	<?php<script type="text/javascript">
	 PHPのコードJavaScriptのコード
	?></script>

JavaScriptの基本構文

異なるパターン

  javascript:"JavaScriptのコード"

イベント時やBookmarkletを書くときなど。

JavaScriptの基本構文

外部ファイルを読み込む場合

 <script type="text/javascript" src="file.js">
 </script>

中身に何も無くても閉じタグが必要

PHPとの構文の違い

変数

  <script type="text/javascript">
    a = 1;
  </script>

変数の頭に$はつけない。

PHPとの構文の違い

文字列結合演算子

  <script type="text/javascript">
    a = 1 + 2;
    alert(a); //3が出力される

    b = "1" + "2";
    alert(b); //12が出力される
  </script>

JavaScriptには
文字列結合演算子(PHPの.(ドット))は無く
数値加算演算と同じものを使用する。

PHPとの構文の違い

数値演算の詳細

  //数値+数値以外は文字として扱われる
   alert(  1  +  2 );  //数値 + 数値 : 数値演算
   alert( "1" +  2 );  //数字 + 数値 : 文字演算
   alert(  1  + "2" ); //数値 + 数字 : 文字演算
   alert( "1" + "2" ); //数字 + 数字 : 文字演算

   //数字を数値にするにはparseInt()を使用する
   a = parseInt("1");
   b = parseInt("2");
   alert(a + b);      //3が出力される

でも...

PHPとの構文の違い

文字列結合演算子その3

 <script type="text/javascript">
   alert( "1" - "2" ); // 引き算 -1
   alert( "1" * "2" ); // 掛け算 2
   alert( "1" / "2" ); // 割り算 0.5
   alert( "1" % "2" ); // 余り 1
 </script>
 

加算以外はPHPっぽく処理してくれます

PHPとの構文の違い

スコープ

  <script type="text/javascript">
    function hoge(){
     var a = 10;
    }
    a = 5;
    hoge();
    alert(a); //105が出力される
  </script>

PHPとは違い、通常は関数内でもグローバル変数

→varをつけるとそのスコープ内でのみ有効な変数となる

オブジェクト

オブジェクト指向のおさらい

PHPでの書き方

	<?php
	 $hoge = new Hoge();
	 インスタンス
	 echo $hoge->hogehoge;
	       プロパティ
	 $hoge->hogehoge();
	     メソッド
	?>

オブジェクトの関係は"->"(アロー演算子)で表す

オブジェクト指向のおさらい

JavaScriptでの書き方:

	<script type="text/javascript">
	 hoge = new Hoge();
	 インスタンス(繰り返すけど変数に$はつけない)
	 alert( hoge.hogehoge );
	       プロパティ
	 hoge.hogehoge();
	    メソッド
	</script>

オブジェクトの関係は"."(ドット)で表す

オブジェクトの種類

Stringオブジェクト

具体例(Stringオブジェクト)

 <script type="text/javascript">
  //Stringオブジェクトのインスタンス生成
  str = new String("abcde");
  
  //lengthプロパティ(文字数)を出力
  alert(str.length);//5が出力される
 </script>

インスタンスだからプロパティが使える...と思うだろ?

具体例(Stringオブジェクト)

 <script type="text/javascript">
  //文字列を変数に代入
  var str = "abcde";
  
  //lengthプロパティ(文字数)を出力
  alert(str.length);//5が出力される
 </script>

実はただの変数でも使えるし

具体例(Stringオブジェクト)

 <script type="text/javascript">  

  //lengthプロパティ(文字数)を出力
  alert("abcde".length);//5が出力される

 </script>

そもそも、ただのリテラル(文字列)でも使える

具体例(Stringオブジェクト)

 <script type="text/javascript">
  //Stringオブジェクトのインスタンス生成
  str = new String("abcde");
  
  //そのまま出力
  alert(str);//abcdeが出力される
 </script>

逆にalertとすると
そのままの文字列が出力される

具体例(Stringオブジェクト)

 <script type="text/javascript">  
  var var_str = "abcde";
  var obj_str = new String("abcde");

  //等しい
  if(var_str == obj_str){
    alert("trueです");
  }
 </script>

っていうか、JavaScript的にも等しかったりする

具体例(Stringオブジェクト)

リテラルとインスタンスって同じもの?

違うよ。全然違うよ。

具体例(Stringオブジェクト)

検証その1 : 両者は本当に等しいのか?

  var var_str = "abcde";
  var obj_str = new String("abcde");

  //typeof:変数の型を調べる関数
  alert( typeof(var_str) ); //string
  alert( typeof(obj_str) ); //object

あくまでリテラルはリテラルで、オブジェクトはオブジェクト

具体例(Stringオブジェクト)

検証その2 : リテラルはオブジェクトなのか?

  var var_str = "abcde";
  var obj_str = new String("abcde");

  //適当なプロパティに代入
  var_str.hoge = "hoge";
  obj_str.hoge = "hoge";

  alert(var_str.hoge);//undefined
  alert(obj_str.hoge);//hoge

オブジェクトはプロパティを持つけど、変数(リテラル)は不可

具体例(Stringオブジェクト)

結局どういうことかというと

つまり自動で型変換をしているってこと!

Arrayオブジェクト

配列オブジェクト

JavaScriptでは配列もオブジェクトです

  //基本形
  var arr = new Array();
  arr[0] = "foo";
  arr[1] = "bar";
  arr[2] = "hoge";

  alert( arr[0] ); //fooが出力される

配列オブジェクト

PHPと異なる点

 var arr = new Array();
 arr[10] = "foo";

 //添え字の一番大きい値+1が出力される
 alert( arr.length ); //11が出力される

 alert( arr[0] ); //undefinedが出力される
 alert( arr[20] ); //undefinedが出力される

lengthプロパティは「要素数」ではないので注意

配列オブジェクト

PHPと異なる点

 var arr
 arr[0] = "foo";

 alert( arr[0] ); //何も出力されない

ただの変数を配列のように扱うことは出来ない

配列オブジェクト

リテラル

 var arr = ["foo", "bar", "hoge"];

 alert( arr[0] ); //fooが出力される

Stringに文字列リテラルがあったように、
Arrayにも配列リテラルがある

配列オブジェクト

リテラル

 //[]、カンマで区切ると配列リテラルとなる
 var arr = ["foo", "bar", "hoge"];

 alert( arr.length );//3が出力される

 //ちなみにStringの例のような書き方も出来る
 alert( ["foo", "bar", "hoge"].length ); //3
 alert( ["foo", "bar", "hoge"][0] );     //foo

newを使わなくても配列を作成できます

配列オブジェクト

ただ困ったことに...

 []、カンマで区切ると配列リテラルとなる
 var arr = ["foo", "bar", "hoge"];

 alert( typeof(arr) ); //object

 arr.hoge = "hoge";
 alert( arr.hoge ); //hogeが出力される

文字列の場合と異なり
配列の場合はオブジェクト扱いになります。

配列には「Stringに対する文字列」が無いし、しょうがないよね。。。

Objectオブジェクト

Objectオブジェクト

連想配列もオブジェクト

 var obj = new Object();

 obj["a"] = "aaa";
 obj["b"] = "bbb";

 alert(obj["a"]);//aaaが出力される

連想配列とか言ってますけど...

Objectオブジェクト

やっぱり中身はオブジェクトです

 var obj = new Object();

 obj["a"] = "aaa";
 obj["b"] = "bbb";

 alert(obj.a);//aaaが出力される

JavaScriptの場合、連想配列というのはオブジェクトのことです

Objectオブジェクト

当然逆も可能です

 var obj = new Object();

 obj.a = "aaa";
 obj.b = "bbb";

 alert(obj["a"]);//aaaが出力される

ただ、違いはあります

Objectオブジェクト

違い

 var obj = new Object();

 obj["a"] = "aaa";
 obj["b"] = "bbb";

 var b = "a";

 alert(obj[b]);//aaaが出力される
 alert(obj.b); //bbbが出力される

連想配列の場合は変数でアクセスが出来る

Objectオブジェクト

ちなみに

 var obj = new String("hoge");

 obj["a"] = "aaa";
 obj["b"] = "bbb";

 var b = "a";

 alert(obj[b]);//aaaが出力される
 alert(obj.b); //bbbが出力される

Objectだけが出来るわけではなく、
オブジェクトなら何でもいけます

Objectオブジェクト

リテラル

 var obj = {a:"aaa", b:"bbb",};

 alert( arr.a );    //aaaが出力される
 alert( arr["a"] ); //aaaが出力される

ObjectにもObjectリテラルがある

Functionオブジェクト

関数オブジェクト

JavaScriptでは関数もオブジェクトです

 var func = 
  new Function("arg1", "alert(arg1);");
 //              ↑引数 ↑処理本体
 func("hoge");

↓こう書いているのと見た目は一緒

 function func(arg1){
  alert(arg1);
 }
 func("hoge");

関数オブジェクト

PHPと異なる点

関数オブジェクト

関数が変数という例その1

 //関数定義
 function hoge(){
  alert("hoge!");
 }
 var hoge = "hoge";

 hoge();//?

関数hogeは文字列リテラルによって
上書きされているので、何も実行されない

関数オブジェクト

関数が変数という例その2

 //関数定義
 function hoge(){
  alert("hoge!");
 }

 var func_var = hoge;

 func_var();//hoge!

func_varにhogeと同一参照先を指定するので、func_varを関数として実行するとhogeと同じ処理が実行される

関数オブジェクト

関数が変数というストレートな例

 var func_hoge = alert;

 func_hoge("hogehoge!");//hogehoge!

func_hogeにalertの処理と同じ参照先を指定することにより、func_hogeがalertと同じ処理を実行出来るようになる

関数オブジェクト

リテラル

 var func_var = function(){alert("hoge!");};

 func_var();//hoge!と出力される

先程と同様、関数にも関数リテラルがある

関数オブジェクト

まとめ

以上のことを踏まえた上で

JavaScriptの
オブジェクト指向

オブジェクト指向

関数にnewつけるだけ

 //普通に関数宣言
 function func(){
 }

 //関数を呼ぶときにnewをつけるだけ
 var obj = new func();
 
 //プロパティ追加
 obj.prop = "hoge";
 
 //出力
 alert(obj.prop);

JavaScriptでは関数と(PHPにおける)クラスの違いはありません

オブジェクト指向

クラス変数(プロパティ)

 //thisを使う
 function func(arg){
  this.prop = arg;
 }

 //関数を呼ぶときにnewをつける
 var obj = new func("hoge");
  
 //出力
 alert(obj.prop);

プライベート変数の扱いは基本的にはPHPと同じ

オブジェクト指向

クラス関数(メソッド)

 //関数と変数は同じなので
 function func(arg){
  this.prop = arg;
  this.meth = function(){alert(this.prop);};
 }

 //関数を呼ぶときにnewをつける
 var obj = new func("hoge");
  
 //出力
 obj.meth();

変数と関数が同じものだと理解できれば納得です

オブジェクト指向

リテラル

 //{}と:と,を使う
 var obj = {
  //ここで定義したものはオブジェクト固有の値になるので
  //thisは不要
  prop : "hoge",
  meth : function(){alert(this.prop);}
 }

 //出力
 obj.meth();

あくまでオブジェクト(インスタンス)用のリテラルであることに注意

まとめ

感謝

質疑応答

ご清聴ありがとうございました