[2019/04/16] JavaScript jQueryの使い方(セレクタ)その2 (No.92)
[2019/04/15] JavaScript jQueryの使い方(セレクタ) (No.91)
[2019/04/04] JavaScript 何に使う (No.89)
[2019/03/07] JavaScript 関数の宣言について(function) (No.87)
[2019/03/04] JavaScript 配列の繰り返し処理(for, for…in, for…of, Array.forEach) (No.86)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
前回は jQuery のセレクタの使い方の基本的な方法として HTMLの要素 , id名 , class名 を単独での使い方を説明しましたが、 今回はそれらを複合的に組み合わせて使う方法について説明します。
組み合わせの方法としては、AND的な方法とOR的な方法があります。 AND的な方法とはセレクタの中で要素を連続で記述し、要素を絞り込むことです。 OR的な方法とはセレクタを列挙してどれにでも該当させることです。
■「HTMLの要素」AND「HTMLの要素」
HTMLの要素同士のANDのセレクタの例を以下に示します。
ボタンクリックイベントの関数宣言の中で div タグと p タグのAND指定を行っています。
2つのdiv タグと p タグの指定の間には空白を入れます。空白が無いと別々のものと判定ができません。
ボタンをクリックした時に全ての div タグで囲まれたHTML要素の内部の全ての p タグのテキストが「ああああああああ」に変わります。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p>メッセージあああ</p> <div> メッセージ0<br /> <p>メッセージ1</p> <p>メッセージ2</p> <p>メッセージ3</p> </div> <p>メッセージいいい</p> <div> <p>メッセージ4</p> </div> <button class="btn">変更</button> <script> $(function () { //<button class="btn">のクリックイベントの関数を宣言 $(".btn").click(function(){ //<div>要素内の<p>の全てのTEXTを変更 $("div p").text("ああああああああ"); }) }); </script> </body>
上の例を以下に実際のHTMLで示します。
⇒「HTMLの要素」AND「HTMLの要素」の例
■「HTMLの要素」AND「class名」
HTMLの要素とclass名のANDのセレクタの例を以下に示します。
div タグと class名 指定を連続して指定します。 class名 指定は先頭に .(ドット) を付けます。
この連結する時に「HTML要素名」と「class名」の間に空白を入れない場合と入れる場合で意味合いが異なります。
空白を入れない場合は指定した「HTML要素名」のclassが、指定した「class名」であるものが対象となります。
また、空白を入れる場合は指定した「HTML要素名」の中のHTML要素でclassが指定した「class名」であるものが対象となります。
以下の例では、ボタンのクリック関数の最初の処理で <div class="msgchg"> のテキストが全て「ああああああああ」に変わります。 (注意するのは <p>メッセージA</p> が全て「ああああああああ」に置き換わることです)
2番目の処理では div タグで囲まれたHTML要素の内部の class="msgchg" の p タグのテキストが「いいいいいいいい」に変わります。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p>メッセージあああ</p> <div class="msgchg"> <p>メッセージA</p> </div> <div> メッセージ0<br /> <p class="msgchg">メッセージ1</p> <p>メッセージ2</p> <p>メッセージ3</p> </div> <p>メッセージいいい</p> <button class="btn">変更</button> <script> $(function () { //<button class="btn">のクリックイベントの関数を宣言 $(".btn").click(function(){ //<div>要素の<class="msgchg">の全てのTEXTを変更 $("div.msgchg").text("ああああああああ"); //<div>要素内の要素が<class="msgchg">の全てのTEXTを変更 $("div .msgchg").text("いいいいいいいい"); }); }); </script> </body> </html>
上の例を以下に実際のHTMLで示します。
⇒「HTMLの要素」AND「class名」
■「class名」AND「class名」
「class名」同士のANDのセレクタの例を以下に示します。class名 指定は先頭に .(ドット) を付けます。
この連結する時に「class名」と「class名」の間に空白を入れない場合と入れる場合で意味合いが異なります。
空白を入れない場合は、classの中が複数指定された「class名」を持つHTML要素が対象となります。
また、空白を入れる場合は最初に指定した「class名」を持つHTML要素内部に、2番目に指定した「class名」持つHTML要素が対象となります。
以下の例では、 ボタンのクリック関数の最初の処理でclassが class="divchg msgchg" のテキストが全て「ああああああああ」に変わります。 (「メッセージ3」「メッセージ4」のところが「ああああああああ」となります)
2番目の処理ではclassが class="divchg" のHTML要素の内部のclassが class="msgchg" のHTML要素のテキストが「いいいいいいいい」に変わります。 (注意するのは「メッセージ3」のところが2つの処理に該当するため、表示が「いいいいいいいい」となります)<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p>メッセージあああ</p> <div class="divchg"> メッセージ0<br /> <p class="msgchg">メッセージ1</p> <p>メッセージ2</p> <p class="divchg msgchg">メッセージ3</p> </div> <p>メッセージいいい</p> <div> <p class="divchg msgchg">メッセージ4</p> </div> <button class="btn">変更</button> <script> $(function () { //<button class="btn">のクリックイベントの関数を宣言 $(".btn").click(function(){ //1個の要素のクラスが<class="divchg msgchg">の全てのTEXTを変更 $('.divchg.msgchg').text("ああああああああ"); //<class="divchg">の<div>要素内の<class="msgchg">の全てのTEXTを変更 $('.divchg .msgchg').text("いいいいいいいい"); }); }); </script> </body> </html>
上の例を以下に実際のHTMLで示します。
⇒「class名」AND「class名」
■「class名」OR「class名」
「class名」同士のORのセレクタの例を以下に示します。class名 指定は先頭に .(ドット) を付けます。
「class名」を ,(カンマ) で連結することで指定された「class名」を持ったHTML要素が対象となります。
以下の例では、classが class="msgchg1" class="msgchg2" class="msgchg5" class="msgchg6" の要素のテキストが全て「ああああああああ」に変わります。<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p>メッセージあああ</p> <div> <p class="msgchg1">メッセージ1</p> <p class="msgchg2">メッセージ2</p> <p class="msgchg3">メッセージ3</p> </div> <p class="msgchg4">メッセージ4</p> <div> <p class="msgchg5">メッセージ5</p> </div> <p class="msgchg6">メッセージ6</p> <button class="btn">変更</button> <script> $(function () { //<button class="btn">のクリックイベントの関数を宣言 $(".btn").click(function(){ //指定された複数クラスの要素のTEXTを変更 $('.msgchg1,.msgchg2,.msgchg5,.msgchg6').text("ああああああああ"); }); }); </script> </body> </html>
上の例を以下に実際のHTMLで示します。
⇒「class名」OR「class名」
PR -
JavaScript の中でなんで jQuery なのかと思われるでしょうが、 jQuery を使うことで JavaScript では記述が長い部分をコンパクトにできたり、 ブラウザ毎で動作の違いを吸収してくれます。 また、jQuery で記述されたプラグインを使うことで、ページに新しい機能が追加できます。
「JavaScript 何に使う」の記事の中で以下の様なソースがあります。 (ソースを少し変更しましたが)<html> <head> <meta charset="utf-8"> <title>test 1-2</title> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <script> var element = document.getElementById('msg1'); element.innerText = 'こんにちは1'; var element = document.getElementById('msg2'); element.innerText = 'こんにちは2'; </script> </body> </html>
■jQueyを使った簡単な例
document.getElementById の記述が少し冗長だと思いますので、 この部分に jQuery の記述を適用してみます。
$('#msg1') の部分が document.getElementById('msg1') の替わりで、 .text('こんにちは1') の部分が .innerText = 'こんにちは1' の替わりになります。
結構シンプルな記述になりました。 ここで $(function(){ ... }); の中で処理の記述がありますが、この関数の中身の実行は全ページの読込後に行われます。 $(document).ready(function(){ ... }); としても同じです。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <script> $(function(){ $('#msg1').text('こんにちは1'); $('#msg2').text('こんにちは2'); }); </script> </body> </html>
$('#msg1') に注目して下さい。 msg1 は p タグの id として宣言されていますが、 id 属性のタグを参照するものしてとして #(シャープ) を使います。 この$('...') と記述するものをセレクタといいます。
セレクタとは全HTMLの中の、どの要素なのかを示すオブジェクトです。 このセレクタですが、 p タグの様なHTMLのタグそのものを示したり、 上のソースの様にID属性のタグや、Class属性のタグを示すことができます。
セレクタの方法はいっぱいありますので、下の方で説明したいと思います。
■jQueyのダウンロード
ところで jQuery の読込ですが、上の例では公式サイトに存在するスクリプトを読込んでいます。 このスクリプトファイルを自分のサイトにダウンロードしてそれを読込ことでもできます。 ダウンロードは以下の公式サイトからできます。
■jQueryのダウンロードサイト
公式サイトには jquery-3.2.1.min.js と min無しの jquery-3.2.1.js の2種類がありますが、 min無しの方はスクリプト内の空白を全て削除してあるため、ファイルサイズが小さいので ロード時間的には有利です。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="スクリプトを設置したアドレス/jquery-3.2.1.min.js"></script> </head> ...
■jQueyのセレクタ
セレクタの方法は HTMLの要素 , id名 , class名 等があり、またそれらを複合的に組み合わせたものがあります。
■HTMLの要素
最初にHTMLの要素のセレクタの例を以下に示します。 $("button") でボタン要素を指し示します。
さらに .(ドット) で繋ぐことでそのセレクタの示すプロパティ、メソッド等にアクセスできます。 $("button").click(function(){ ... }) はボタンのクリックイベントの関数宣言を行います。
この関数の中の $("p") は p タグの要素全てを示しますので、ボタンをクリックした時に全ての p タグの表示が「こんにちは」に変わります。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <button>変更</button> <script> $(function () { //HTML要素<button>のクリックイベントの関数を宣言 $("button").click(function(){ //HTML要素<p>の全てを変更 $("p").text("こんにちは"); }) }); </script> </body>
上の例を以下に実際のHTMLで示します。
⇒HTMLの要素の例
■id名
HTML要素に設定された id名 でセレクタを限定します。 セレクタの書式としては $("#id名") の様に id名 の前に #(シャープ) を付けます。 HTML要素の中に id名 が複数存在しても最初の要素が対象となります。 (jQuery の大元の getElementById 関数は最初の要素しか取得しないからです。)
2個のボタンはそれぞれ id名 が btn1 , btn2 と設定されているので、 それぞれのクリック時のイベント関数を宣言しています。 それぞれの関数の中では p タグの msg1 , msg2 に対応してテキストを変更しています。<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <button id="btn1">変更1</button> <button id="btn2">変更2</button> <script> $(function () { //<button id="btn1">のクリックイベントの関数を宣言 $("#btn1").click(function(){ //<p id="msg1">のTEXTを変更 $("#msg1").text("11111"); }) //<button id="btn2">のクリックイベントの関数を宣言 $("#btn2").click(function(){ //<p id="msg2">のTEXTを変更 $("#msg2").text("22222"); }) }); </script> </body>
上の例を以下に実際のHTMLで示します。
⇒id名の例
■class名
HTML要素に設定された class名 でセレクタを限定します。 セレクタの書式としては $(".class名") の様に class名 の前に .(ドット) を付けます。 HTML要素の中に class名 は複数存在する可能性があるので、それら全てが対象となります。
class名 が btn と設定されたボタンのクリック時のイベント関数を宣言しています。 関数の中では msg > と設定された全ての p タグに対してテキストを変更しています。 (以下の例では3個の p タグのテキストを変更しています。)<html> <head> <meta charset="utf-8"> <title>test jQuery</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <p class="msg">テストメッセージ1</p> <p class="msg">テストメッセージ2</p> <p class="msg">テストメッセージ3</p> <button class="btn">変更</button> <script> $(function () { //<button class="btn">のクリックイベントの関数を宣言 $(".btn").click(function(){ //<p class="msg">の全てのTEXTを変更 $(".msg").text("ああああああああ"); }) }); </script> </body>
上の例を以下に実際のHTMLで示します。
⇒class名の例
以上、セレクタの基本的な使い方でしたが、次回はこれらの複合的な使い方を説明したいと思います。
-
JavaScript とはブラウザで実行されるクライアントプログラムのことですが、 HTMLで記述されたWebページを動的に変更したりするために使います。
主なjavaScriptの機能としては以下の様なものがあります。■HTML要素の操作(HTMLの要素の属性値、CSSプロパティを変更、HTML要素そのものの生成)
以下のソースを見て下さい。 これは p タグで囲って テストメッセージ を表示するだけの HTML ソースです。 これをブラウザ表示させると テストメッセージ が表示されます。
<html> <head> <meta charset="utf-8"> <title>test 1</title> </head> <body> <p>テストメッセージ</p> </body> </html>
この p タグの中身を変更するには JavaScript のソースを以下の様に記述します。
このソースをブラウザで表示させるといきなり こんにちは が表示されます。
body タグに記述された script タグの中の JavaScript のソースが順次実行されるため、 このソースを読込むと同時に JavaScript のソースが実行され こんにちは のみが表示されます。<html> <head> <meta charset="utf-8"> <title>test 1</title> </head> <body> <p>テストメッセージ</p> <script> var elements = document.getElementsByTagName('p'); elements[0].innerText = 'こんにちは'; </script> </body> </html>
上のソースでいきなり document オブジェクトが出てきましたが、 これはブラウザーに読み込まれたウェブページ全体を示すオブジェクトです。 このオブジェクトの getElementsByTagName メソッドを使ってタグのオブジェクトの一覧を取得します。
getElementsByTagName に 'p' を指定し、p タグの一覧を取得します。 結果はオブジェクト配列となりますので、上の例では配列の最初のプロパティ innerText へ こんにちは を設定します。
ここで テストメッセージ を1行追加して以下の様にし、 ブラウザに表示すると、当然なのですが最初の1行目しか こんにちは となりません。 そこで、 JavaScript 部分を以下の様にすれば全てのp タグの中身のテキストを こんにちは に変更できます。<html> <head> <meta charset="utf-8"> <title>test 1</title> </head> <body> <p>テストメッセージ</p> <p>テストメッセージ</p> <script> var elements = document.getElementsByTagName('p'); for (var i = 0; i < elements.length; i++) { elements[i].innerText = 'こんにちは'; } </script> </body> </html>
getElementsByTagName 複数のタグの一覧を取得しますが、特定のオブジェクト(エレメント)を取得したい場合があります。 その場合には getElementById で指定した ID名 のオブジェクトが取得できます。
以下のソースでは各 p タグに ID を別な名前で割り当てています。 JavaScript では2行目の ID を指定して getElementById を呼出します。 返されたオブジェクトの innerText へ こんにちは を設定します。<html> <head> <meta charset="utf-8"> <title>test 1-2</title> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <script> var element = document.getElementById('msg2'); element.innerText = 'こんにちは'; </script> </body> </html>
■HTML要素などによる動作の指定
上の例では、ソースをブラウザで表示したとたんにメッセージが変化していましたが、 これでは面白くないので、ボタンを2個設置して、ボタンを押下した時にそれぞれのメッセージが変化する様に ソースを変更してみます。
<html> <head> <meta charset="utf-8"> <title>test 1-3</title> </head> <body> <p id="msg1">テストメッセージ</p> <p id="msg2">テストメッセージ</p> <button onclick="changeMsg('msg1');">msg1</button> <button onclick="changeMsg('msg2');">msg2</button> <script> //メッセージ変更関数 function changeMsg(strId) { var element = document.getElementById(strId); element.innerText = 'こんにちは'; } </script> </body> </html>
上のソースでは各ボタン要素のマウスクリックイベントが発生した時に、関数 changeMsg を呼出す様にしています。
実際に以下のボタンをクリックして下さい。 テストメッセージ が こんにちは に変化します。テストメッセージ
テストメッセージ
onclick の様なイベントは他にもいろんなものがありますが、以下に一部を示します。 必要に応じて各イベントの処理を行います。- onkeydown :キーが押した時のイベント
- onkeyup :キーを放した時のイベント
- ondblclick :マウスの左ボタンをダブルクリックした時のイベント
- onmouseover:マウスのカーソルを要素の上に合わせた時のイベント
- onmouseout :マウスのカーソルを要素の上から外した時のイベント
いろんな動作に関してのイベント処理の例は別の機会に追々紹介したいと思います。
■Webサーバとの通信によるデータのやり取り(Ajaxを利用)
Webページ上でページを移動しないで、サーバからデータを取得し一部分を動的に変更したい場合があります。 この時に用いる方法がAjax(Asynchronous JavaScript XML)と言われるものです。 JavaScript でサーバ側から渡されるXMLデータ(JSONデータもできます)をページ上に反映させます。 手順としては以下の通りです。
- クライアント側からサーバ側にデータ取得等に必要な引数等を送信する
- サーバ側は引数データを受け取って返信すべきデータを整形しクライアント側に送信する
- クライアント側はサーバ側から受信したデータをページ上に表示する
Ajax の処理には XMLHttpRequest というオブジェクトを使います。 XMLHttpRequest のメソッド、プロパティは以下の通りです。
メソッド 説明 open(method, url
[, async [, user[, pass]]])新しく作成されたリクエストを初期化する
method : HTTP リクエストメソッド("GET", "POST", ...)
url : リクエストを送信する URL を表す
async : 操作が非同期的に行われるかどうかを示します
user : 認証プロセスで使用するユーザー名
pass : 認証プロセスで使用するパスワードsend([body]) リクエストをサーバーに送信します
body : POST リクエストの場合に使用しますabort() メソッドは、すでに送信された要求を中止します プロパティ 説明 onreadystatechange EventHandler で、これは readyState 属性が変化する度に呼び出されます readyState リクエストの状態を返します
(0):UNSENT XMLHttpRequest クライアントは作成済みだが、まだ open() メソッドは呼ばれていない
(1):OPENED open() が呼び出し済み
(2):HEADERS_RECEIVED send() は呼び出し済みでレスポンスヘッダーを受け取り済み
(3):LOADING レスポンスボディを受け取り中。ResponseType が "text" か空文字の場合、responseText はロードするごとに部分テキストを持つ
(4):DONE 取得操作が完了している(データ転送が完全に成功したか失敗したかどちらか)responseText リクエストに対するレスポンスがテキスト形式で入った DOMString を返すか、 リクエストが失敗した場合や、まだ送信されていない場合は null を返す responseXML リクエストに対するレスポンスが入った Document を返すか、 またはリクエストが成功しなかった場合、まだ送信されていない場合、 XML または HTML として解釈できなかった場合は null を返す status リクエストに対するレスポンスのステータスを返す statusText HTTP サーバーから返ってきたレスポンス文字列が入った DOMString を返す
以下に Ajax 処理の簡単な例を示します。 このソースで行われるのは、ボタンを押下した時にAjax処理関数を呼出します。 Ajax の手順は以下の通りです。- XMLHttpRequest オブジェクトの生成
- サーバへのリクエストの設定を行う(ここでは GET でこのソースが存在するディレクトリのテキストファイルが対象)
- イベントハンドラの登録(データ受信が完了でステータスが正常の場合、受信データを表示)
- リクエストをサーバーに送信
イベントハンドラの登録では、ここで処理が動作するわけでは無く、単に関数の登録のみを行っています。 XMLHttpRequest オブジェクトの readyState プロパティの値が変化した時に起動される関数を定義しています。 結果的にこの関数が走るのは send された後になります。
<html> <head> <meta charset="utf-8"> <title>test ajax</title> </head> <body> <h1>test ajax</h1> <p id="msg1">テストメッセージ</p> <button onclick="getAjax();">Ajax</button> <script> //Ajax関数 function getAjax() { //XMLHttpRequestの生成 var xhr = new XMLHttpRequest(); //サーバへのリクエストの設定を行う xhr.open('GET', 'test_ajax.txt'); //イベントハンドラの登録 xhr.onreadystatechange = function () { if (xhr.readyState == 4) { //データ受信完了 if (xhr.status == 200) { //ステータスが正常の場合、返信データを表示 var elem = document.getElementById("msg1"); elem.innerText = xhr.responseText; } else { alert("status = " + xhr.status); } } }; //リクエストをサーバーに送信 xhr.send(); // xhr.abort(); } </script> </body> </html>
実際の Ajax 処理では上記の様に XMLHttpRequest そのものでプログラムするわけでは無く、 JQuery と呼ばれるライブラリを利用し、もっと簡略化された記述で処理を行います。 この辺りは別の機会に紹介したいと思います。
-
関数はJavaScriptで繰り返し行う処理などをまとめたものを言います。 他の言語を使っている方には特に説明は必要無いかとは思いますが、 JavaScript特有の記述もあります。 関数の宣言方法の違いによって以下の2種類がありますので、それぞれについて見ていきます。
■一般的な関数の宣言(functionを使った宣言)
function キーワードを使った関数宣言の構文は以下の様になっています。 function キーワードの後に「関数名」を書いて関数の引数が在れば「引数リスト」(複数あれば「,」カンマで区切ります)を記述します。 関数内部には行いたい処理を記述し、最後に関数として戻したい値があれば return 文で戻してやります。
function 関数名( [ 引数リスト ] ) { // 関数内の処理 ... [return [戻り値];] }
基本的な使い方は以下のソースを見て下さい。
func1 という名前で関数を宣言しています。1から引数に与えられた数値までの合計を計算する簡単な関数です。 本来ならば、引数の値チェック(数値以外の文字列等が渡されたらどうするか)や、合計値の桁あふれなどにもチェックが必要かもしれません。
取敢えずこの関数を実行するために、関数の戻り値を変数に代入しています。 尚、戻り値を直接別の関数に渡すことも可能です。(以下では console.log への引数の値として渡されます)//関数の宣言(引数までの合計を計算) function func1( intPara ) { var sum = 0; for (var i = 1; i <= intPara; i++) { sum = sum + i; } return sum; } //変数の宣言 var val; //関数の実行 val = func1(10); // 変数への代入 console.log(val); // 55 と表示される console.log(func1(100)); // 5050 と表示される
「引数」が文字列の場合を想定した関数の例を以下に示します。//関数の宣言(引数に文字列指定) function func2( strPara1, strPara2 ) { var strRet = "" + strPara1 + "..." + strPara2; return strRet; } //関数の実行 console.log(func2("10", "aaaa")); // 10...aaaa と表示される
関数の戻り値としてオブジェクトを指定
関数の戻り値としてオブジェクトを指定できます。以下にその例を示します。
関数としては2個の引数を持ち、それぞれをオブジェクトのプロパティの値として設定しています。 関数の実行後、戻り値をそのままコンソールに表示すれば結果はオブジェクトが戻されることが分かります。
ここで注意が必要なのですが、関数の引数としては数値でも文字列でも指定できますので オブジェクトのプロパティ値もそれぞれ設定したままが戻されます。//関数の宣言(戻り値がオブジェクトの場合) function func3( strPara1, strPara2 ) { //オブジェクトの宣言 var obj = { Para1: strPara1, Para2: strPara2, } //オブジェクトを戻す return obj; } //関数の実行(変数の宣言も同時に行う) var val = func3(100, "aaaa"); console.log(val); // Object { Para1: 100, Para2: "aaaa" } と表示される console.log(val.Para1); // 100 と数値として表示される console.log(val.Para2); // aaaa と文字列として表示される val = func3("100", "aaaa"); console.log(val); // Object { Para1: "100", Para2: "aaaa" } と表示される console.log(val.Para1); // 100 と文字列として表示される console.log(val.Para2); // aaaa と文字列として表示される
上の例でもありますが、引数の型等をどの様に定義するかは関数を作る前によく考えておく必要があります。
関数の引数としてオブジェクトを指定
引数にArrayやユーザ定義のオブジェクトを指定できますが、 関数内でそのオブジェクトのプロパティを変更すると、関数の呼出元にも反映されるため注意が必要です。 以下にその例を示します。
//関数の宣言(引数がオブジェクトの場合) function func4( objPara ) { //プロパティを変更 objPara.prop1 = "000"; } //オブジェクトの宣言 var obj = { prop1: "1234" , prop2: "abc" }; console.log(obj); // Object { prop1: "1234", prop2: "abc" } と表示される //関数の呼出 func4( obj ); console.log(obj); // Object { prop1: "000", prop2: "abc" } と表示される //----- //関数の宣言(引数がArrayの場合) function func5( arr ) { //配列の内容を変更 arr[1] = "111"; } //Arrayの宣言 var arr = new Array("aaa", "bbbb", "123"); console.log(arr); // Array(3) [ "aaa", "bbbb", "123" ] と表示される //関数の呼出 func5( arr ); console.log(arr); // Array(3) [ "aaa", "111", "123" ] と表示される
引数にオブジェクト、及びArrayの場合を例にしましたが、関数内でのプロパティの変更が 関数外にも影響していることが分かります。
■関数式(関数リテラル)による宣言
今までは function キーワードを使った構文としての関数宣言でしたが、 関数式として宣言することができます。
//関数式による関数の宣言 var test = function (strPara) { //引数の前後に括弧([])を付加して戻す return "[" + strPara + "]"; }; //ここで文の最後であるセミコロン「;」を記述(無くてもOKですが) //関数の実行 var str = test("12345"); console.log(str); // [12345] と表示される //ちなみに「test」を表示する console.log(test); // function test()... と表示される
上の例からもわかりますが var test と変数 test を宣言しているようですが、 test の実体は関数として存在しますので、これを関数の様に呼出すことができます。
ただし関数式は名前をつけることもでき、関数内で自身を参照することができます。 以下の例では、1から引数値までの総和を求める処理を行っています。 sum と言う名前を関数に付けて自分自身の中で再帰的に呼び出しを行い、 引数値から順次1小さい値を加算することを再帰的に行っています。//[1~N]までの総和を求める関数を関数式で宣言 var summation = function sum(intPara) { if (intPara <= 1) { //1になったらそこで再帰呼出し終了 return 1; } else { //再帰呼出しで順次1小さい値を加算してゆく return intPara + sum(intPara - 1); } }; //関数の実行 console.log(summation(1)); // 1 と表示される console.log(summation(2)); // 3 と表示される console.log(summation(3)); // 6 と表示される console.log(summation(10)); // 55 と表示される console.log(summation(100));// 5050 と表示される
関数式で宣言した関数オブジェクトを引数にした関数を宣言し、 それぞれの関数式での関数を呼び分ける方法を以下に記します。//関数オブジェクトを引数にした関数宣言 function math(fn, val) { //関数オブジェクトを実行 return fn(val); } //関数式による引数を2乗する関数宣言 var sqr = function(val) { return val * val; }; //関数式による引数を +1 する関数宣言 var inc = function(val) { return val + 1; }; //関数式による引数を -1 する関数宣言 var dec = function(val) { return val - 1; }; //関数式による引数を2倍する関数宣言 var mul2 = function(val) { return val * 2; }; //関数オブジェクトを変えて関数をコールする console.log(math(sqr, 10)); // 100 と表示される console.log(math(inc, 10)); // 11 と表示される console.log(math(dec, 10)); // 9 と表示される console.log(math(mul2, 10)); // 20 と表示される
-
配列の繰り返し処理では通常 for 文を使います。
for 文には一般的に指標を使って繰り返し、指標で配列を参照する方法や、 配列の指標と値を順次取得できる方法があります。
尚、for 文には以下の使い方がある様ですので、それぞれについて見ていきます。- for(指標を使った一般的な方法)
- for...in(オブジェクトのプロパティ名での繰返し)
- for...of(オブジェクトのプロパティの値の繰返し)
- Array.forEach(配列の各要素についての繰返し)
■for(指標を使った一般的な方法)
いまさらですが for 文の構文は以下の様になっています。 「初期値設定」「条件式」「指標処理」の3個の部分を「;」セミコロンで区切ります。 それぞれを [] で囲っているのは、必要が無ければ記述を省略できます。 (通常はあまり使いませんが)
for ( [ 初期値設定 ]; [ 条件式 ]; [ 指標処理 ] ) { // 繰り返しの処理 ... }
基本的な使い方は以下のソースを見て下さい。
最初に3個の要素を持つ配列を宣言し、次に for で配列の長さ分の処理を行います。
配列の長さを取得するために length プロパティを参照しますが、 このプロパティは、配列の宣言を行った時に javascript が内部で設定されます。
繰返し処理の中身は配列の値をコンソールに表示することを行います。 (10 20 30 と順次表示されます。)//配列の宣言 var arr = [10, 20, 30]; //配列の内容を順次表示 for(var i = 0; i < arr.length; i++) { //繰返しの処理... console.log(arr[i]); }
「初期値設定」「条件式」「指標処理」の3個の部分はそれぞれ必要が無ければ記述しなくても問題ありません。 究極、3個とも無くしてしまってもOKです。 但し、ループを抜ける処理は記述しないと無限ループになってしまいます。
このループを抜ける処理が break 文でループを抜けたい条件の中で記述します。 (条件が無くてもOKですが...)
上の処理と同じことを行う例を示します。//配列の宣言 var arr = [10, 20, 30]; //指標の宣言 var i = 0; //for 文の中身は記述しない for( ; ; ) { if (i >= arr.length) { //length の値は「3」 //指標が長さ以上になった場合ループを抜ける break; } //ループ内処理 console.log(arr[i]); //指標を増やす i++; } //break 後はここに来る
break 文が出たところで continue 文を出さないと片手落ちなので以下の例を示します。 指標が「1」になった時に、指標を+1してループの先頭に戻しています。 結果としてコンソールには 10 30 が表示されます。//配列の宣言 var arr = [10, 20, 30]; //配列の内容を順次表示 var i = 0; //for 文の中身は記述しない for( ; ; ) { if (i >= arr.length) { //指標が長さ以上になった場合ループを抜ける break; } if (i == 1) { //指標を増やす i++; //指標が[1]ならば先頭に戻る:「if (i >= arr.length) {」の処理に戻る continue; } //ループ内処理 console.log(arr[i]); //指標を増やす i++; } //break 後はここに来る
■for...in(オブジェクトのプロパティ名での繰返し)
for 文なので配列に使えるのかなと思って、以下の例を実行したのですが、 コンソールに表示されるのは「0 1 2」と指標らしきものが表示されます。 なぜ指標なのかを正式なドキュメントに当たると以下の様に記されています。
「for..in 文は、指定したオブジェクトの列挙可能プロパティに対して、順不同で反復処理をします。」
つまり返されるのはプロパティ名を返す様です。 (単純な配列の場合は指標がプロパティ扱いの様です。//配列の宣言 var arr = [10, 20, 30]; //配列の内容を順次表示 for(var v in arr) { console.log(v); }
そこで以下の様にオブジェクトに対して for 文を行うと、コンソールには「prop1 prop2 prop3」が順次表示されます。 これはオブジェクトのプロパティ名そのものです。//オブジェクトの宣言 var obj = { prop1: 10, prop2: 20, prop3: 30 }; //オブジェクトのプロパティ名を順次表示 for(var v in obj) { console.log(v); }
さらに以下の様にプロパティ名を扱うと、プロパティに対応する値にアクセスできます。
//オブジェクトの宣言 var obj = { prop1: 10, prop2: 20, prop3: 30 }; //オブジェクトの内容を順次処理 var sum = 0; var str = ""; for(var v in obj) { sum += obj[v]; // 数値として加算 str += obj[v]; // 文字列として追加 } console.log(sum); // 60 と表示される console.log(str); // 102030 と表示される
先ほどの配列の場合は以下の様にすれば、指標に対応する値にはアクセスできますが、 指標の順番通り取得できるとは限らないので、指標によるアクセスの方が良いようです。 (以下の例の様に配列の個数が少ない場合は順番にアクセスされる様ですが..)//配列の宣言 var arr = [10, 20, 30]; var sum = 0; //配列の内容を順次表示 for(var v in arr) { sum += arr[v]; // 数値として加算 } console.log(sum); // 60 と表示される
■for...of(オブジェクトのプロパティの値の繰返し)
for...in ではオブジェクトのプロパティ名での繰り返し処理でしたが、 for...of はオブジェクトのプロパティの値を順次アクセスできるものです。
但し対象となるものは iterable(繰り返し可能)なオブジェクト らしいです。 配列(Arrayで宣言されたもの)や、String、Map などです。//---------- //配列の宣言 var arr = [ 10, 20, 30 ]; //配列の値を順次表示 for(var v of arr) { console.log(v); } //コンソールに以下の3行で表示される // 10 // 20 // 30 //---------- //Stringの宣言 var str = "ABC"; //Stringの文字を順次表示 for(var v of str) { console.log(v); } //コンソールに以下の3行で表示される // A // B // C //---------- //Mapの宣言 var M = new Map([["a", 1], ["b", 2], ["c", 3]]); //Mapの要素を順次表示 for (var ent of M) { console.log(ent); } //コンソールに以下の3行で表示される // Array [ "a", 1 ] // Array [ "b", 2 ] // Array [ "c", 3 ] //Mapのキーと値を順次表示 for (var [key, value] of M) { console.log(key + "=" + value); } //コンソールに以下の3行で表示される // a=1 // b=2 // c=3
■Array.forEach(配列の各要素についての繰返し)
Arrayオブジェクトのメソッドである forEach を使っても繰り返し処理が行えます。 構文は以下の通りです。
arr.forEach(function callback( value [, index [, array ] ] ) { //your iterator }[, thisArg]); パラメーター: callback: 各要素に対して実行するコールバック関数で、3つの引数をとります。 value: 現在処理されている配列の要素。 index: 現在処理されている配列の要素のインデックス。 array: forEachが適用されている配列。 thisArg: callback 内で this として使用する値 (i.e the reference Object)。
forEach の例を以下に示します。
//配列の宣言 var arr = ['a', 'b', 'c']; //配列を順次処理 arr.forEach(function(val, idx) { console.log("arr[" + idx + "] = " + val); }); //コンソールに以下の3行で表示される // arr[0] = a // arr[1] = b // arr[2] = c