アトリエ・エクレア

2DCG&3DCG, プログラミング, 日記などを掲載してます。

JavaScript

JavaScript



<参考>

  • Mozilla Developer Network   → リンク
  • Mozilla Developer Network (DOMリファレンス)   → リンク
  • JavaScriptリファレンス   → リンク


<JavaScriptの特徴>

  • オブジェクト指向言語。
  • オブジェクトのデータ型に区別はない。
  • 継承はプロトタイプベースの機構を通して行われる。
  • プロパティとメソッドは、どのオブジェクトにも動的に追加できる。
  • 変数のデータ型は宣言が不要(動的型付け)。
  • ハードディスクには自動的に書き込みできない。
  • ステートメントの終わりのセミコロン(;)は、省略できる。
  • thisキーワードの値は、関数の呼ばれ方によって異なるので注意。


<書き方>

  • script要素内に書く。
  • head要素とbody要素の中の、どちらに書いてもいい。
  • 空白と改行は無視される。
  • 大文字、小文字は区別する。
  • 文末の" ; "セミコロンを忘れないようにすること。
  • テキストは " か ' で囲むが、HTMLの属性と混同しないように ' を主に使用すると良さそう。
  • JavaScriptの記述場所
    • HTMLファイル内で、分割して記述(変数はそのファイル内で保持)
    • HTMLファイル内で、一箇所にまとめて記述(head要素内など)
    • 別ファイルとして記述

<コマンドラインに書く場合>

  • Firefoxの場合、F12(またはCtrl+Shift+I)で開発者ツールが開く。→ コンソールタブに切り替える。※Webコンソール(Ctrl+Shift+K)
  • Google Chromeの場合、F12(またはCtrl+Shift+I)でデベロッパーツールが開く。→ Consoleタブに切り替える。

コマンドライン(コマンドプロンプト)に、プログラムを入力し、Enterキーで実行。

alert("Hello, World!");  // Windowオブジェクトの、alert()メソッド

コンソールに出力

console.log("Hello, World!");  // Windowオブジェクトの、consoleプロパティ

<HTML内部に書く場合>
※ script要素(<script>タグ)における、type属性の初期値は、type="text/javascript"である。
よって、JavaScriptの場合にはtype属性の指定を省略できる。

  <!DOCTYPE html>
  <html lang="ja">
  <head>
   <meta charset="UTF-8" />
   <title>htmlテンプレート</title>
   <link rel="stylesheet" href="my-reset.css" type="text/css" />
   <link rel="stylesheet" href="my-css.css" type="text/css" />
   <script>var value = 15;</script>
  </head>
  <body>
   <script>document.write('<p>変数の値は' + value + 'です。<p>');</script>
  </body>
  </html>

<HTML外部に書く場合>

  <!DOCTYPE html>
  <html lang="ja">
  <head>
   <meta charset="UTF-8" />
   <title>htmlテンプレート</title>
   <link rel="stylesheet" href="my-reset.css" type="text/css" />
   <link rel="stylesheet" href="my-css.css" type="text/css" />
   <script src="my-javascript.js"></script>
  </head>
  <body>
   <p>テンプレートです。</p>
   <img src="img/test.jpg" />
  </body>
  </html>


<コメント>

HTMLのコメント

  <!-- HTMLの一行コメント -->
  
  <!-- HTMLの
  複数行のコメント -->

CSSのコメント

  /* CSSの一行コメント */

  /* CSSの
  複数行のコメント */

JavaScriptのコメント

  // JavaScriptの一行コメント ※改行まで有効

  /* JavaScriptの一行コメント */

  /* JavaScriptの
  複数行のコメント */


<データ型>

以下の 7 つの型が定義されている。

  • 6つのデータ型はプリミティブ型
    • 真偽値 (Boolean) :  true または false
    • null :  null値を意味する特殊なキーワード。null は Null や NULL などとは異なる。
    • undefined :  値が未定義のトップレベルプロパティ。
    • 数値 (Number) :  25 や 3.14159 など。
    • 文字列 (String) :  "Hello" など。
    • シンボル (Symbol) :  インスタンスが固有で不変となるデータ型。
  • オブジェクト (Object)


<変数の宣言と、値の代入>

変数の宣言方法

  • キーワードvarを使う。ローカル変数とグローバル変数、両方の宣言が可能。
    ※但し、関数(or メソッド)の仮引数の宣言にはvarは使わない。
  • キーワードletを使う。ブロックスコープのローカル変数を宣言できる。
  • 単純に変数に値を代入する。常にグローバル変数として宣言される。※非推奨。

初期値なしで宣言された変数の値は、undefined となる。

グローバル変数の場合

その文書のどのコードからも使用できる変数。
変数を関数の外側で宣言する。
グローバル変数は、グローバルオブジェクトのプロパティとなる(WebページでのグローバルオブジェクトはWindow)。

  var value;    // 宣言してから、
  value = 15;   // 値を代入

  var value = 15;  // 宣言と同時に値を代入

  function myFunc() {
   value = 15;  // 関数内での、var無し宣言 ※非推奨
  }

ローカル変数の場合

関数またはブロック内でしか使用できない変数。
変数を関数の内部で宣言する。
または、ブロック内でletを用いて変数を宣言する。

  function myFunc() {
   var value = 15;  // 宣言だけして後から値代入でもOK
  }


<定数>

constキーワードを用いて、読み取り専用の名前付き定数を作成できる。
代入によって値を変えたり、スクリプト実行中に再宣言することはできない。
値で初期化しなければならない。

  const teisuu = "<p>定数です</p>";
  document.write(teisuu);


<データ型>

  • プリミティブ型(6つ):
    • Boolean(true または false)
    • null
    • undefined(値が未定義のトップレベルプロパティ)
    • Number(75 や 3.14159 など)
    • String("Howdy" など)
    • Symbol(ECMAScript 6 の新機能。インスタンスが固有で不変となるデータ型)
  • オブジェクト型


<条件分岐>

if文

  var value = 30;
  if (value != 10) {
   document.write('<p>10ではない。</p>');
  }

if~else文

  var value = 30;
  if (value >= 10) {
   document.write('<p>10以上です。</p>');
  } else {
   document.write('<p>10未満です。</p>');
  }

if~else if~else文

  var value = 30;
  if (value <= 10) {
   document.write('<p>10以下です。</p>');
  } else if (value <= 20) {
   document.write('<p>10より大きく、20以下です。</p>');
  } else {
   document.write('<p>20より大きいです。</p>');
  }

switch文

  var value = 30;
  switch (value) {
  case 10:
   document.write('<p>値は10です。</p>');
   break;
  case 20:
   document.write('<p>値は20です。</p>');
   break;
  case 30;
  case 40:
   document.write('<p>値は30または40です。</p>');
   break;
  default: // 省略可
   document.write('<p>値は10,20,30,40以外です。</p>');
   break;
  }


<繰り返し処理>

for文

  for (var i=0; i<10; i++) {
   document.write('<p>' + i + '</p>');
  }

while文

  var value = 1;
  while (value <= 10) {
   document.write('<p>' + value + '</p>');
   value++;
  }

do~while文

  var value = 1;
  do {
   document.write('<p>' + value + '</p>');
   value++;
  } while (value <= 10);


<繰り返し処理から抜ける>

break文

  for (var i=0; i<10; i++) {
   if(i == 7) {
    break;       // ループを抜ける
   }
   document.write('<p>' + i + '</p>');
  }

continue文

  for (var i=0; i<10; i++) {
   if(i == 7) {
    continue;       // 次のループに移る
   }
   document.write('<p>' + i + '</p>');
  }


<配列リテラル、オブジェクトリテラル>

配列リテラル

var array = [20, 45, 'sample'];    // 右辺は、配列リテラル
// var array = new Array(); array[0] = 20; array[1] = 45; array[2] = 'sample'; と意味的に同じ

console.log(array[0]);     // 20
console.log(array[1]);     // 45
console.log(array[2]);     // sample

オブジェクトリテラル

var obj = {x:10, y:20};    // 右辺は、オブジェクトリテラル
// var obj = new Object(); obj.x = 10; obj.y = 20; と意味的に同じ

console.log(obj.x);     // 10
console.log(obj.y);     // 20

console.log(obj['x']);     // 10
console.log(obj['y']);     // 20


<配列>

  • 配列は、名前やインデックスで参照できる値からなる、順序付けされた集合。
  • JavaScriptは、明確な配列データ型を持っていない。
    しかし、配列として機能する定義済みの Arrayオブジェクトとそのメソッドを利用できる。
  • 実装レベルでは、JavaScriptの配列は、そのインデックス値をプロパティ名として使うことで、標準のオブジェクトプロパティとして要素を格納している。
  • Arrayオブジェクトのlengthプロパティは、常に、最終要素のインデックス値 + 1 を返す。
    つまり、必ずしも要素の数と一致するわけではないので要注意。
  • JavaScriptの配列は、各要素に異なるデータ型の値を格納することができる。※他の言語との違いに注意
  // 同じ配列が作成される
  var myArray = new Array(element0, element1, ..., elementN);
  var myArray = Array(element0, element1, ..., elementN);
  var myArray = [element0, element1, ..., elementN];   // ブラケットで要素を囲む ※配列リテラル(配列初期化子)
  var bread = ['あんぱん', 'しょくぱん', 'カレーパン'];  // ブラケットで要素を囲む ※配列リテラル(配列初期化子)
  // または、
  // var bread = new Array('あんぱん', 'しょくぱん', 'カレーパン');  // 引数が1つ、且つ、数値である場合、挙動が異なるので要注意

  // Arrayオブジェクトのlengthプロパティで要素数(※厳密には、最終要素のインデックス値 + 1)を取得
  for (var i=0; i < bread.length; i++) {               
   document.write('<p>' + bread[i] + '</p>');          // 添え字を利用して出力
  }
  var myArray1 = [75];      // 数値 75 という要素を 1個 だけ持つ配列
  
  var myArray2 = Array(75); // 要素がなく、arr.length が 75 に設定された配列
  // 以下と同様
  // var myArray2 = [];
  // myArray2.length = 75;
  // 非ゼロの長さを持つが、アイテムのない配列を生成 ※この例でのarrayLengthは数値とする
  var myArray = new Array(arrayLength);
  var myArray = Array(arrayLength);
  
  // 上記2つのステートメントは、いずれも以下と同じ結果になる。
  // ※同じ結果となるには、arrayLengthは数値である必要がある。
  //   数値でない場合、単一の要素(指定した値)を持つ配列が生成される。
  var myArray = [];
  myArray.length = arrayLength;


<配列の、様々な操作>

// 配列を作成する
var bread = ["あんぱん", "しょくぱん", "カレーぱん"];
console.log(bread);                        // Array ["あんぱん", "しょくぱん", "カレーぱん"]
 
// 配列の要素数を取得する ※厳密には要素数ではなく、"最後の要素のインデックス + 1 " の値
console.log(bread.length);                 // 3
 
// 配列の要素を取得する
var first = bread[0];
console.log(first);                        // あんぱん
var last = bread[bread.length - 1];
console.log(last);                         // カレーぱん
 
// 配列の最後に要素を追加する
var newLength = bread.push("ジャムぱん");   // 配列の最後に、1つ以上の要素を追加し、新しいlengthプロパティを返す
console.log(newLength);                    // 4
console.log(bread);                        // Array ["あんぱん", "しょくぱん", "カレーぱん", "ジャムぱん"]
 
// 配列の最後の要素を削除する  ※空の配列(lengthプロパティが0)に実行した場合、undefinedを返す
var last = bread.pop();                    // 配列の最後の要素を削除し、削除した値を返す
console.log(last);                         // ジャムぱん
console.log(bread);                        // Array ["あんぱん", "しょくぱん", "カレーぱん"]
 
// 配列の先頭の要素を削除する  ※空の配列(lengthプロパティが0)に実行した場合、undefinedを返す
var first = bread.shift();                 // 配列の先頭の要素を削除し、続く添え字を小さい方向にずらし、削除した値を返す
console.log(first);                        // あんぱん
console.log(bread);                        // Array ["しょくぱん", "カレーぱん"]
 
// 配列の先頭に要素を追加する
var newLength = bread.unshift("あんぱん");  // 配列の先頭に、1つ以上の要素を追加し、新しいlengthプロパティを返す
console.log(newLength);                    // 3
console.log(bread);                        // Array ["あんぱん", "しょくぱん", "カレーぱん"]
 
// 要素のインデックスを取得する
var pos = bread.indexOf("カレーぱん");
console.log(pos);                          // 2
 
// インデックスで要素を指定して、削除・追加する  ※第1引数:変更開始のindex, 第2引数:取り除く要素数, 第3引数以降:追加する要素を指定可
var pos = bread.indexOf("しょくぱん");
var removedItem = bread.splice(pos, 1);    // 指定位置の要素を削除し、続く添え字を小さい方向にずらし、削除した要素を含む"配列"を返す
console.log(removedItem);                  // Array ["しょくぱん"]
console.log(bread);                        // Array ["あんぱん", "カレーぱん"]
 
// 配列のコピー
// 配列の一部を取り出して新しい配列を返す。
// 第1引数:取り出し開始のindex  ※省略した場合、0番目の要素から開始する。
// 第2引数:取り出し終了のindex(それ自体は含めず、直前まで取り出す) ※省略した場合、配列の最後まで取り出す。
var copyArray = bread.slice();             // 配列のコピーを作成
console.log(copyArray);                    // Array ["あんぱん", "カレーぱん"]
 
// 配列のループ処理    ※与えられた関数を、配列の各要素に対して一度ずつ実行する
bread.forEach(
  function (currentValue, index, array) {  // 各要素に対して実行するコールバック関数で、3つの引数をとる
    console.log(index, currentValue);
  }
);
// 0 あんぱん
// 1 カレーぱん


<多次元配列>

二次元配列

var food =[
  ["あんぱん", "しょくぱん", "カレーパン"],
  ["しょうゆラーメン", "みそラーメン", "とんこつラーメン"],
  ["カツ丼", "天丼", "牛丼"]
];

document.write(food[1][2]);    // とんこつラーメン

二次元配列 ※動的な作成

var COL = 5;   // 行数
var ROW = 3;   // 列数

// 二次元配列を作成 ※要素は空
myArray = new Array();
for(var i = 0; i < ROW; i++){
  myArray.push(new Array(COL));  // COLの数の空要素を持つ配列の追加を、ROWの数だけ繰り返す
}

// 値を代入
for(var y = 0; y < ROW; y++){
  for(var x = 0; x < COL; x++){
    myArray[y][x] = x + y;       // 右辺の計算式は、特に意味は無い
  }
}


<配列の作成とコピー>

配列変数はArrayオブジェクトへの参照をしているので、配列変数を単純に代入すると参照の代入になる。
このため、コピーをするには、新たにArrayオブジェクトを作成する必要がある。
※Array.prototype.slice()を利用する方法もある。

// 配列の作成
var myArray1 = [1,2,3];

// 配列のコピー
var myArray2 = new Array();
for(var i = 0; i < myArray1.length; i++){
	myArray2[i] = myArray1[i];
}
// 2次元配列の作成
var myArray1 = [ [1,2,3], [4,5,6], [7,8,9] ]:

// 2次元配列のコピー
var myArray2 = new Array();
for(var i = 0; i < myArray1.length; i++){
	myArray2[i] = new Array();
	for(var j = 0; j < myArray1[i].length; j++){
		myArray2[i][j] = myArray1[i][j];
	}
}


<DOM (Document Object Model)>

ブラウザオブジェクトは、Windowオブジェクトを頂点とした、階層構造になっている。
下の階層のオブジェクトは、上の階層のオブジェクトのプロパティからアクセスできる。
以下は、ブラウザオブジェクトの一部。

Windowオブジェクト

windowプロパティは、そのWindowオブジェクト自身を指す。
EventTargetオブジェクトから、プロパティとメソッドを継承する。

// ------------------------------------------------------------------
// プロパティ
// ------------------------------------------------------------------
// 例1
var doc = window.document;   // windowに含まれるdocumentへの参照を返す

// 例2
var str = "hello, world!";
window.console.log(typeof str);   // デバッガのWebコンソールにメッセージを出力

// ------------------------------------------------------------------
// メソッド
// ------------------------------------------------------------------
// 例1
function helloworld() {
  alert("hello, world!");
}
window.addEventListener("click", helloworld, false); // type, listener, Capture

// 例2
window.alert("Hello world!");  // 警告ダイアログ(テキストとOKボタン)を表示

// ------------------------------------------------------------------
// イベントハンドラ
// ------------------------------------------------------------------
// 例1
function helloworld() {
  alert("hello, world!");
}
window.onload = helloworld; // windowのloadイベントに対応するイベントハンドラ
// window.onload = function() {
//   alert("hello, world!");
// }

// 例2
// windowのmousedownイベントに対応するイベントハンドラ
window.onmousedown = function() {
  alert("hello, world!");
}

Documentオブジェクト

ブラウザに読み込まれたWebページを表す。
Nodeオブジェクト、自身の親、EventTargetオブジェクトから、プロパティとメソッドを継承する。
※Windowオブジェクト直下の階層。

// ------------------------------------------------------------------
// プロパティ
// ------------------------------------------------------------------
// 例1
vor myBody = document.body;    // 現在のdocumentの<body>要素の、取得/設定

// 例2
vor myTitle = document.title;  // 文書のタイトルを取得/設定

// ------------------------------------------------------------------
// メソッド
// ------------------------------------------------------------------
// 例1
var myImg = document.createElement("img");   // 指定の要素名の要素を生成
myImg.src = "mypicture.png";
document.body.appendChild(myImg);

// 例2
document.write("<p>段落</p>");     // ドキュメントにテキストを書き込む

// 例3
// 指定のCSSセレクタにマッチする、文書中の最初の要素を取得
// ※単発のクラス名の場合は getElementsByClassName()メソッドの方が高速
// ※IDセレクタの場合は getElementById()メソッドの方が高速
var elm = document.querySelector(".myClass");  // 文書中の、myClassクラスを持つ要素の内、最初のもの

// 例4
// 指定のCSSセレクタにマッチする、文書中の要素の全てのリスト(NodeListオブジェクト)を取得
var elms = document.querySelectorAll(".myClass");  // 文書中の、myClassクラスを持つ全ての要素のリスト(NodeListオブジェクト)

HTMLElementオブジェクト

HTML要素を表す。※全てではなく、このオブジェクトから派生したものもある。
Elementオブジェクトからプロパティとメソッドを継承する。
GlobalEventHandlersオブジェクトからプロパティを継承する。

a

Elementオブジェクト

ドキュメントの一部分を表す。ここの種類の要素に共通するプロパティとメソッドを持つ。
Nodeオブジェクト、自身の親、EventTargetオブジェクトから、プロパティとメソッドを継承する。

// ------------------------------------------------------------------
// プロパティ
// ------------------------------------------------------------------
// 例1
document.body.innerHTML = "";  // 内容を空の文字列に置き換える
document.body.innerHTML = "<p>hello, world!</p>";

// 例2
var elm = document.querySelector("#jet");
if (elm.className == "airplane") {            // 要素のclass属性の値の取得/設定
  alert("クラス名はairplaneです。");
}

// ------------------------------------------------------------------
// メソッド
// ------------------------------------------------------------------
// 例1  対象要素の子孫の内、引数に指定したCSSセレクタにマッチする最初の要素を返す
var elm = document.body.querySelector('p');       // body要素の中で、最初のp要素のみ

// 例2  対象要素の子孫の内、引数に指定したCSSセレクタにマッチする要素群のNodeListオブジェクトを返す
var elms = document.body.querySelectorAll('p');   // body要素の中で、全てのp要素のリスト(NodeListオブジェクト)

Nodeオブジェクト

a

a

EventTargetオブジェクト

a

a


<組み込みオブジェクト ※一部>

Arrayオブジェクト

 

Stringオブジェクト

 

Mathオブジェクト

数学的な定数と関数を提供するプロパティとメソッドを持つ。
Mathオブジェクトの全てのプロパティとメソッドは、静的。

// プロパティ
var piValue = Math.PI;         // 円周率。約3.14159
var sqrt2Value = Math.SQRT2;   // 2の平方根。約1.414

// メソッド
var randomValue = Math.random();    // 0 以上 1 未満の乱数を返す
var absoluteValue = Math.abs(-15);  // 引数として与えた数の絶対値を返す

ラジアンと、度(°)の変換

// 三角関数は、角度をラジアンで受け取り、戻り値もラジアンとなる。
// 1ラジアンは、180/π 度に相当 (360°は2πラジアン, 180°はπラジアン)

// ラジアンから度(°)へ変換: 180/Math.PI で乗算
// 度(°)からラジアンへ変換: 180/Math.PI で除算

var rad = deg * (Math.PI / 180);
var deg = rad * (180 / Math.PI);

Dateオブジェクト

 

Numberオブジェクト

 

<ユーザー定義のオブジェクト>

  • オブジェクトは、プロパティの集まりからなり、またそのプロパティは名前(あるいはキー)と値との関連付けから成り立っている。
  • プロパティの値を関数にすることもでき、これはいわゆるオブジェクトのメソッドとなる。
  • オブジェクトのプロパティは、オブジェクトに関連付けられている変数。
  • オブジェクトは連想配列

オブジェクト初期化子の利用(リテラル表記法)

// プロパティは、識別子、数値、または文字列リテラルのいずれか
var obj = { property1:   value1,   // プロパティ:値,  ※識別子、
            2:           value2,   // プロパティ:値,  ※数値
            "property3": value3 }; // プロパティ:値   ※文字列リテラル

コンストラクタ関数の利用

// コンストラクタ
function Birthday(day, month, year) {  // 慣習的に、1文字目は大文字
  this.day = day;       // thisキーワードは、カレントオブジェクトを指す
  this.month = month;
  this.year = year;
}

var bd1 = new Birthday(5, 10, 2016);  // new演算子で、オブジェクトのインスタンスを作成
var bd2 = new Birthday(6, 12, 2016);  // new演算子で、オブジェクトの実体を増やす
// コンストラクタ
var Birthday = function (name) {  // 無名関数を利用
  this.name = name;
  console.log("Happy Birthday! " + this.name);
};

var bd1 = new Birthday("Suzuki");  // コンストラクタは、インスタンス化の際に呼び出される
var bd2 = new Birthday("Sato");

<プロパティの追加>

実行時にどのオブジェクトにもプロパティを追加することができる。
プロパティに値を代入することでプロパティを定義する事ができる。
しかし、同じ型の全てのオブジェクトに新しいプロパティを追加するには、
そのオブジェクト型の定義に、そのプロパティを追加する必要がある。

var birthday = new Object();
birthday.day = 6;         // プロパティに値を代入することでプロパティを定義する事ができる
birthday.month = 12;
birthday.year = 2016;
birthday.comment = "Happy Birthday!";

// ブラケット表記法でも、アクセスや設定が可能
birthday["day"] = 6;
birthday["month"] = 12;
birthday["year"] = 2016;
birthday["comment"] = "Happy Birthday!";

<例) オブジェクトの生成1>

// オブジェクトの作成
var object = new Object();

// プロパティを付与
object.foo = "bar";
object.age = 42;
object.baz = {myProp: 12};

// メソッドを定義
object.myFunc = function(){
  console.log("Hello, World!");
}

// プロパティへのアクセス
object.foo;           // "bar"  ※ドット表記法によるアクセス
object["age"];        // 42     ※ブラケット表記法によるアクセス
object.foo = "baz";
object.baz.myProp     // 12

// メソッドの利用
object.myFunc();

<例) オブジェクトの生成2>

// リテラル表記法によるオブジェクトの生成 
var object = {
  // キーと値のペアのリスト
  foo: "bar",
  age: 42,
  baz: {myProp: 12},
  myFunc: function(){   // メソッドの定義
    console.log("Hello, World");
  }
  // myFunc(){console.log("Hello, World!");}  // 短縮できる ※簡略構文では、無名関数の代わりに、名前付き関数を使用
}

// プロパティを持たない空のオブジェクトの生成
// var object = {};

// プロパティへのアクセス
object.foo;           // "bar"  ※ドット表記法によるアクセス
object["age"];        // 42     ※ブラケット表記法によるアクセス
object.foo = "baz";

// メソッドの利用
object.myFunc();


<this参照>

  • 関数の、thisキーワードは、JavaScriptでは、ほかの言語と少々異なる動作をする。
  • strictモードと、非strictモードで違いがある。
  • ほとんどの場合、this の値は、関数の呼ばれ方によって決定される。
    → 実行時に割り当てできず、関数が呼び出されるたびに異なる可能性がある。

<グローバル コンテクストでのthis>

  • グローバル実行コンテクスト(いずれかの関数の外側)では、
    strictモードか否かにかかわらず、thisはグローバルオブジェクトを参照する。
this.x = 25;

console.log(this);     // Window
console.log(this.x);   // 25
console.log(window.x); // 25

<関数コンテクストでのthis>

  • 関数内では、thisの値は、関数の呼び出され方によって異なる。
  • strictモードではない場合、thisの値は常にオブジェクト。既定ではグローバルオブジェクトに設定される。
  • strictモードでは、thisの値は実行コンテクストに入ったときに設定された値が残る。
    定義されていない場合は、undefined が残る。
// strictモードではない場合
function myFunc(){
  return this;
}

console.log(myFunc());  // Window ※グローバルオブジェクト
// strictモードの場合
function myFunc(){
  "use strict";         // strictモード
  return this;
}

console.log(myFunc());  // undefined

<オブジェクトのメソッド内でのthis>

  • 関数がオブジェクトのメソッドとして呼び出されるとき、その this にはメソッドが呼び出されたオブジェクトが設定される。
  • this のバインディングは、最直近のメンバー参照にのみ影響を受ける。
/* これはエラーになる ※他のプロパティに直接アクセスはできない
var test = {
  str: "Hello, World!",
  myFunc: function(){console.log(str);}  // この例では、strが参照できずにエラーとなる。
};

test.myFunc();
*/

// thisキーワードを使い、他のプロパティにアクセス
var myObject = {
  str: "Hello, World!",
  myFunc: function(){console.log(this.str);}  // ここでのthisは、このインスタンスを示す
};

myObject.myFunc();   // メソッド内のthisに、myObjectオブジェクトが関連付けられる

<コンストラクタ関数内でのthis>

  • 関数がコンストラクタとして(new キーワードとともに)使用されるとき、そのthisは生成された新しいオブジェクトにバインドされる。
// コンストラクタ関数
function MyConstructor(){
  this.x = 36;
}

var myObject = new MyConstructor();
console.log(myObject.x); // 36


// コンストラクタ関数
function MyConstructor2(){
  this.x = 12;
  // コンストラクタの既定では、thisで参照されるオブジェクトを返すが、代わりにほかのオブジェクトを返すことができる。
  // 戻り値がオブジェクトではない場合、thisオブジェクトが返される。
  return {x: 78};
}

myObject = new MyConstructor2();
console.log(myObject.x); // 78

<イベントハンドラ内でのthis>

  • 関数がイベントハンドラとして使用される場合、その this にはイベントを発生させた要素が設定される。
var myObject = {
  x: 35,
  myFunc: function(){console.log(this.x);}  // 52 ※thisはイベントを発生させた要素(ここではWindow)を指す
};

var x = 52;
window.addEventListener('click', myObject.myFunc, false);  // イベントリスナーの設定
/*
function MyConstructor(){
  this.x = 35;

  // イベントリスナーの設定
  window.addEventListener('click', function(){console.log(self.x);}, false);  // undefined ※thisはイベントを発生させた要素(ここではWindow)を指す
}

var myObject = new MyConstructor();
*/


// 対応策
function MyConstructor(){
  this.x = 35;
  var self = this;   // このインスタンスを変数に入れておく ※変数名は任意だが、selfが一般的
  // イベントリスナーの設定
  window.addEventListener('click', function(){console.log(self.x);}, false);  // 35 ※このインスタンスのプロパティ x
}

var myObject = new MyConstructor();


<関数>

functionステートメントは、静的な構造を宣言するため、
関数呼び出しの記述が前でも後でも問題ない。

<script>
	// -----------------------------------------------
	function myFunc(str1, str2){
		document.write(str1 + '関数です。' + str2);
	}
	
	myFunc('<p>', '</p>');
	
	// -----------------------------------------------
	document.write('<p>' + myAdd(25, 50) + '</p>');
	
	function myAdd(num1, num2){
		return num1 + num2;        // 戻り値を返す
	}
</script>


<セレクタAPI>

セレクタAPIにより提供されるメソッドで、セレクタのセットにマッチする要素ノードを、
従来のテクニックに比べ、簡単かつ高速にDOMから抽出できる。

※例えば、全称セレクタ(ユニバーサルセレクタ), idセレクタ, classセレクタ,
グループセレクタ, 子セレクタ, 疑似クラスセレクタ, 属性セレクタなどが指定できる。

※Document.querySelectorメソッドについて:
・単発のクラス名の場合は、getElementsByClassName() メソッドの方が高速。
・IDセレクタ( # )の場合は、getElementById() メソッドの方が高速。

// ========================================================================
// 従来
// ========================================================================
// 指定された ID を持つ要素のオブジェクトを返す。
element = document.getElementById(id);
// 与えられたタグ名を持つ要素のリスト(NodeListオブジェクト)を返す。
elements = document.getElementsByTagName(name);
// クラス名で得られる要素の集合(NodeListオブジェクト)を返す。
elements = document.getElementsByClassName(name);
// 指定したname属性値を持つ(X)HTML文書内の要素のリスト(要素のHTMLCollection)を返す。
elements = document.getElementsByName(name);
 
 
// ========================================================================
// セレクタAPIのメソッド
// ========================================================================
// 与えられたCSSセレクタにマッチする文書中の最初の要素のオブジェクトを返す。マッチしない場合はnullを返す。 
element = document.querySelector(selectors);
// 与えられたCSSセレクタにマッチする文書中の要素の全てのリスト(NodeListオブジェクト)を返す。
// マッチしない場合は空のNodeListオブジェクトを返す。 
elementList = document.querySelectorAll(selectors);


<イベント処理>

イベント処理の設定にはいくつかの方法がある。

  1. EventTargetオブジェクトの、addEventListenerメソッドを利用する。
    例) window.addEventListener(イベント,関数名(または無名関数), キャプチャーフラグ)など
  2. イベント系のプロパティを利用する。
    例) window.onload = 関数名(または無名関数)など
    ※onloadなどのようなイベント系のプロパティは、イベントハンドラプロパティとも呼ばれる。
  3. HTML要素(HTMLタグ)のイベント属性に、値として、実行する処理を指定する。
    例) <button type="button" onclick="myEvent();" >ボタン</button>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>サンプル</title>
<script>
	// target.addEventListener(type, listener [, useCapture]);
	// useCapture(オプション)は 省略した場合falseになるが、全ブラウザで省略可能なわけではない。 
	window.addEventListener('load', setName, false);      // イベントリスナーの設定 ※第二引数を無名関数にしても可
  // window.onload = setName; プロパティを利用する方法もある。(関数名か、無名関数を設定する)

	function setName(){
    // querySelectorメソッドでは最初の要素のみ、querySelectorAllメソッドでは全ての要素を扱う
		var mySpans = document.querySelectorAll('span');
		for(var i=0; i<mySpans.length; i++){              // NodeListオブジェクトのlengthプロパティ
			mySpans[i].innerHTML = 'ぽん太';                 // element.innerHTML
		}
	}
</script>
</head>
<body>
<h1><span></span>クエスト</h1>
<p><span></span>は、JavaScriptの呪文を唱えた!</p>
</body>
</html>

<マウスイベント>

※他にもある。


イベント イベント発生のタイミング
click クリックされたとき
dblclick ダブルクリックされたとき
contextmenu 右クリックされたとき
mousedown 上にマウスポインタがある状態で、マウスボタンが押されたとき
mouseup 上にマウスポインタがある状態で、マウスボタンが離されたとき
mouseover マウスポインタが乗ったとき
mouseout マウスポインタが出て行ったとき
mousemove マウスポインタが移動したとき


<ボタンのイベント>

type属性

  • type="submit"     : 送信 ※初期値
  • type="reset"        : リセット
  • type="button"      : 汎用ボタン
window.addEventListener('load', setButton, false);

function setButton(){
	var btn = document.querySelector('#btn1');
	btn.addEventListener('click', btn1event, false);
	
	btn = document.querySelector('#btn2');
	btn.addEventListener('click', btn2event, false);
}

function btn1event(e){    // 引数からMouseEventオブジェクトを利用できる
	// 処理
}

function btn2event(e){
	// 処理
}


<CSSスタイルの設定>

window.addEventListener('load', hide, false);

function hide(){
	var test = document.querySelector('#test');
	test.style.display = 'none';  // styleプロパティからCSSStyleDeclarationオブジェクトを利用
}


<タイマー>

WindowTimersインタフェースは、Windowオブジェクトで実装されている。

  • WindowTimers.setInterval()
  • WindowTimers.setTimeout()

<指定した時間ごとに、何度か処理を実行する場合>

  • window.setInterval() を使って、アニメーションのように何度も実行される関数に遅延をセットする。
  • window.clearInterval() を使って、インターバルをキャンセルする。
var count = 0;
var intervalID;

function myWrite() {
  count++;
  window.document.write('実行されました!');
  if (count == 7) {   // 7回実行
    window.clearInterval(intervalID); // インターバルをキャンセルする
  }
}

// 一定の遅延間隔を置いて関数を繰り返し呼び出す。
// intervalIDは、clearIntervalに渡すことのできる、固有のインターバルID
// ※止めないのであれば、この変数に代入することは必須ではない
intervalID = window.setInterval(myWrite, 2000); // 2000ミリ秒(2秒)毎にmyWriteを繰り返し呼び出す
var myVar = setInterval(myTimer, 1000);

function myTimer() {
  var d = new Date();
  var t = d.toLocaleTimeString();
  document.write(t);
}

<指定した時間後に、一度だけ処理を実行する場合>

  • window.setTimeout() を使って、指定された遅延の後に、関数を実行する。
  • window.clearTimeout() を使って、タイムアウトを中止する。
var isStop = true;
var timeoutID;

function myWrite() {
  window.document.write('実行されました!');   // windowは省略可
}

// 指定された遅延の後に、コードの断片または関数を実行する。
// timeoutIDは、window.clearTimeoutで使われる、数値のID
// ※止めないのであれば、この変数に代入することは必須ではない
timeoutID = window.setTimeout(myWrite, 2000); // 2000ミリ秒(2秒)後に、一度だけmyWriteを呼び出す

if(isStop){
  window.clearInterval(timeoutID); // 遅延の処理をキャンセルする
}


<アニメーション>

Window.requestAnimationFrame() ※WindowTimersインタフェースではない。
次の再描画の前に、アニメーションを更新する指定した関数を呼び出すように要求する。

  • window.requestAnimationFrame() を使って、ブラウザ再描画の前に、関数を実行する。
  • window.cancelAnimationFrame() を使って、コールバック関数の更新を中止する。
 

<要素の、表示・非表示>

var isButtonON = false;         // ON/OFFフラグ

// ボタン
var btn = document.getElementById('toggleButton');
btn.addEventListener('click', switchDisplay, false);

// イベントリスナー
function switchDisplay(e){
  isButtonON = !isButtonON;
  var img = document.getElementById('sampleImage');
  if(isButtonON){    
    img.style.display = 'block';     // 表示
  } else {
    img.style.display = 'none';      // 非表示
  }  
}


<要素の削除>

var img = document.getElementById('sampleImage');

// Node.parentNode  : 指定ノードの、DOMツリー内の親ノードを返す
// Node.removeChild : DOMから子ノードを取り除く
img.parentNode.removeChild(img);    // 要素を削除

マイブログへようこそ♪
PLEASANT_DRAGON

2DCG&3DCG,プログラミング,
日記などを掲載中☆

(*´▽`*)コメント大歓迎です☆

最新記事
記事一覧

全ての記事を表示する

カテゴリ
SAI (0)
mi (2)
C (1)
C++ (1)
C# (0)
VBA (0)
月別アーカイブ
最新コメント
RSSリンクの表示
リンク
FC2ブログランキング

FC2Blog Ranking

ピックアップ商品1♪










カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
ブログ内検索フォーム
プロフィール

エクレア

Author:エクレア


  • 2DCG&3DCGの創作活動をしています。

  • SF系のメカが大好物。

アクセスカウンター
Twitter
ピックアップ商品2♪