[2019/03/01] JavaScript thisキーワードについて (No.85)
[2019/02/27] JavaScript 連想配列の操作について(this キーワード) (No.84)
[2019/02/27] JavaScript 配列の操作について (No.83)
[2019/02/26] JavaScript 連想配列の作成と初期化について (No.82)
[2019/02/26] JavaScript 配列の作成と初期化について (No.81)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
「連想配列の操作について(this キーワード)」の記事の中で 連想配列の様に使えるオブジェクトの説明で、そのオブジェクトの中にメソッドを作成し、 オブジェクト内の変数をアクセスする為に this キーワードを使いました。
⇒JavaScript 連想配列の操作について(this キーワード)
今回はこの this キーワードですが、使う場所によって異なるオブジェクトを指し示すため注意が必要です。
以下の使い方がある様ですので、それぞれについて見ていきます。■グローバル実行コンテクスト
以下のソースを見て下さい。 最初に this キーワードそのものをコンソールにログアウトしています。 結果として this はウインドウオブジェクトであることが分かります。 さらに次のグローバル変数宣言で、ウインドウオブジェクトに value オブジェクトを値「1」で追加します。 これで、ウインドウオブジェクトのプロパティ的に value を参照することが出来ます。
value を「2」として上書きできることも分かります。
ここで注意が必要なのは、存在しない変数をいきなり設定してやると、変数が生成されます。 以下のソースでも value2 が生成されることが分かります。■関数コンテクスト
グローバル関数の宣言を行って、その中で this キーワードで value を参照しています。 表示される結果は、グローバル変数の内容となります。
■オブジェクトのメソッドとして
オブジェクトを宣言し、その中でメソッドも宣言します。 メソッドの中で this を使ってオブジェクト内のプロパティにアクセスしています。 (このメソッドの定義はインラインでの定義と言うそうです。)
//オブジェクト宣言 var objTest = { value: 100, //オブジェクト内のメソッド宣言 logout: function() { console.log("object value = " + this.value); } }; //メソッド実行 objTest.logout(); // object value = 100 と表示される
このインラインのメソッドを、オブジェクトの外で関数として宣言し、 オブジェクトのプロパティに後から追加することもできます。//オブジェクト宣言 var objTest = { value: 200 }; //外側で関数宣言 function _logout() { console.log("object value = " + this.value); } //プロパティに関数を割り当てる objTest.logout = _logout; //メソッド実行 objTest.logout(); // object value = 200 と表示される
この例では、オブジェクトのプロパティを logout と宣言するのと、 そのプロパティを _logout 関数に置き換える処理を一緒に行っています。
一緒に行うのがいやであれば、以下の様にしても同じです。//オブジェクト宣言 var objTest = { value: 200, logout: null //取敢えず先にプロパティ宣言 // logout: 0 }; //外側で関数宣言 function _logout() { console.log("object value = " + this.value); } //プロパティに関数を割り当てる objTest.logout = _logout; //メソッド実行 objTest.logout(); // object value = 200 と表示される
■コンストラクタの呼び出しとして
関数がコンストラクタとして(new キーワードとともに)使用されるとき、 その this は生成された新しいオブジェクトにバインドされます。
以下の例では最初の関数宣言では this を使って内部的にオブジェクトを生成し、そのオブジェクトのプロパティとして value を作り引数の値を設定しています。
この関数をコンストラクタ呼出しを行うと、戻り値としてオブジェクトを返すので、 それを別の変数に代入することで変数を介してそのオブジェクトへアクセスできます。 変数 obj をコンソールに表示させると、オブジェクトが生成されていることが分かります。//関数宣言 function objCreate(pVal) { this.value = pVal; // value プロパティを pVal で設定 } //コンストラクタ呼出しでオブジェクト生成 var obj = new objCreate(100); console.log(obj); // Object { value: 100 } と表示される
もし new キーワードで使用せずに単に関数呼び出しとした場合はどうなるでしょうか。 以下の例を見て下さい。 単なる関数呼び出しでの this はグローバルオブジェクトを示すため、 この場合ですと Window オブジェクトに value プロパティを生成します。//関数宣言 function objCreate(pVal) { this.value = pVal; } //単なる関数呼び出し objCreate(100); console.log(this); // Window { objCreate: function objCreate() , value: 100 ... と表示される
■別オブジェクトのバインド呼び出し(call または apply 呼び出し)
関数本体に this キーワードを使用する場合、call メソッドか apply メソッドを使用した呼び出しで、 その値に特定のオブジェクトをバインドできます。
以下の例はオブジェクト「obj」を宣言し、関数の this の指定が「obj」となっていることを示します。//プロパティ「value」を持つオブジェクト宣言 var obj = { value: "object" }; //グローバルオブジェクトにプロパティ「value」宣言 var value = 'global'; //関数宣言 function objTest() { return this.value; //関数の呼出により[this]の指すものが変わる } var strRet; //通常の関数呼び出し strRet = objTest(); console.log(strRet); // global と表示される //[call]関数呼び出し strRet = objTest.call(obj); // this の指定を「obj」として呼び出し console.log(strRet); // object と表示される //[apply]関数呼び出し strRet = objTest.apply(obj);// this の指定を「obj」として呼び出し console.log(strRet); // object と表示される
call 及び apply の明確な違いは以下の例を見て下さい。 call 呼出しの場合は、 this に対応するオブジェクトの後に引数をそのままの値で設定し、 apply 呼出しの場合は、 this に対応するオブジェクトの後に引数を配列の形で設定します。//関数宣言(引数が3個) function sum(p3, p4, p5) { //[this]によるプロパティ値と引数の値の合計計算 return this.p1 + this.p2 + p3 + p4 + p5; } //プロパティ[p1][p2]を持つオブジェクト宣言 var obj = { p1: 1, p2: 2 }; var ret; //[call]による関数呼び出し ret = sum.call(obj, 3, 4, 5); console.log(ret); // 15 と表示される //[apply]による関数呼び出し ret = sum.apply(obj, [100, 200, 300]); console.log(ret); // 603 と表示される
PR -
連想配列とは各種のKEYに対応する値を持つ配列の様なものであると「連想配列の作成と初期化について」で説明しましたが、 JavaScriptには実際には連想配列は存在せず、オブジェクトのプロパティとして扱うことで連想配列的に扱えます。 以下の様な例があります。
連想配列的宣言
//連想配列の宣言(実際はオブジェクト) var arrVar = { item: "test1", value: 100, func: function() { // 関数の宣言 console.log("TEST"); } }; //配列内の値表示 console.log(arrVar["item"]); // test1 と表示される console.log(arrVar["value"]); // 100 と表示される //関数の実行 arrVar.func(); // TEST と表示される
上の例では arrVar に関数 func を宣言していますが、このままだと何も意味のある処理ではないので arrVar が持つプロパティを表示する様にしてみます。
そこで必要になるのが this キーワードです。 this 「これ」って何といった感じですが、 this が存在するオブジェクトの親オブジェクトを指すと理解すれば良いと思います。
論より実際の処理を見ると分かりやすいです。上の例に少し修正を加えます。this を使った連想配列の項目アクセス
//連想配列の宣言(実際はオブジェクト) var arrVar = { item: "test1", value: 100, func: function() { // 関数の宣言 var str = ""; str += "item = " + this.item; str += ",value = " + this.value; console.log(str); } }; //関数の実行 arrVar.func(); // item=test1,value=100 と表示される
関数 func が呼ばれた時には this が指し示すオブジェクトは、 関数オブジェクト func が属する親オブジェクトになりますので arrVar を指しそれのプロパティへのアクセスが可能になります。
いわゆるオブジェクト参照の変数ですので this を別の変数に代入しても利用できます。this を使った連想配列の項目アクセスその2
//連想配列の宣言(実際はオブジェクト) var arrVar = { item: "test1", value: 100, add: function(pVal) { // value に加算する関数宣言 this.value += pVal; }, func: function() { // 関数の宣言 var obj = this; // this を別の変数に代入 var str = ""; str += "item = " + obj.item; str += ",value = " + obj.value; console.log(str); } }; //関数の実行 arrVar.add(100); //関数の実行 arrVar.func(); // item=test1,value=200 と表示される
関数 func では this を別の変数に代入して処理を行っています。 add という関数を追加してありますが、これは引数の値をプロパティ value に加算処理を行います。
今回使用した this は奥が深いキーワードでいろんな場所で使えるのですが、 詳しい説明は又の機会にしたいと思います。
-
以前の記事では配列の初期化について記しましたが、今回は配列の要素に関しての増減などを行う処理についてです。
⇒JavaScript 配列の作成と初期化について
配列を操作するメソッドには以下の様なものがあります。メソッド 構文 説明 push Array.push( value, ...) 配列の最後尾に要素を追加する。(要素は値そのもの、または配列) pop Array.pop() 配列の最後尾から要素を削除する。 unshift Array.unshift( value, ...) 配列の先頭に要素を追加する。(要素は値そのもの、または配列) shift Array.shift() 配列の先頭から要素を削除する。 concat Array = Array.concat( value, ...) 配列の最後尾に要素を追加し、結果の配列を返す。 slice Array = Array.slice( begin [, end] ) 配列の開始から終了までの要素を別の配列として返す。
終了指定が無い場合は最後の要素までが範囲とする。
(但し終了は含まれない)splice Array = Array.splice( index, howMany, [element1], ... ) 指定配列をindexで指定された位置から、howManyで指定された個数分を取除き、要素を追加する。
戻り値:削除された配列を返す。
index:値が配列の長さより大きい場合、配列の長さと同じ値となります。値が負数の場合、配列の終端からその値を引いた数が開始位置となります。
howMany:配列から取り除く古い要素の数を示す整数。howMany が 0 の場合、どの要素も取り除かれません。
配列の要素への最後尾への追加と削除、及び先頭への追加と削除の例を示します。 要素の追加は1個のみではなく連続して引数として渡せるため、そのままの順番で配列に追加されます。配列への要素の追加と削除
//配列の宣言 var arrStr = ["aaaa", "bb", "ccccc"]; console.log(arrStr); // Array(3) [ "aaaa", "bb", "ccccc" ] と表示される //要素の最後尾追加 : push arrStr.push("dddd"); console.log(arrStr); // Array(4) [ "aaaa", "bb", "ccccc", "dddd" ] と表示される //要素の最後尾削除 : pop arrStr.pop(); // "dddd" 削除 arrStr.pop(); // "ccccc"削除 console.log(arrStr); // Array(2) [ "aaaa", "bb" ] と表示される //複数要素の先頭追加 : unshift arrStr.unshift("dddd", "ee"); console.log(arrStr); // Array(4) [ "dddd", "ee", "aaaa", "bb" ] と表示される //要素の先頭削除 : shift arrStr.shift(); // "dddd"削除 console.log(arrStr); // Array(3) [ "ee", "aaaa", "bb" ] と表示される
上の例では個別の要素を追加する例でしたが、追加処理の引数として配列そのものを指定できます。 以下にその例を示しますが、追加された配列は最初の配列の中の入れ子での配列になってしまいますので注意が必要です。
配列への配列の追加
//配列の宣言 var arrStr = ["aaaa", "bb", "ccccc"]; console.log(arrStr); // Array(3) [ "aaaa", "bb", "ccccc" ] と表示される //配列データの最後尾追加 : push (Array()) var arrStr2 = ["111", "222"]; arrStr.push(arrStr2); console.log(arrStr); // Array(4) [ "aaaa", "bb", "ccccc", ["111", "222"] ] と表示される
この現象を解消する為に concat を使って配列を連結し結果を新しい配列を返す様にします。 concat の戻り値は配列なので新しい配列変数に代入しても、既に在る配列変数に代入することもできます。配列の連結
//配列の宣言 var arrStr = ["aaaa", "bb", "ccccc"]; console.log(arrStr); // Array(3) [ "aaaa", "bb", "ccccc" ] と表示される //第2の配列の宣言 var arrStr2 = ["111", "222"]; //配列を連結し、新しい配列にコピー var arrStr3 = arrStr.concat(arrStr2); console.log(arrStr3); // Array(5) [ "aaaa", "bb", "ccccc", "111", "222" ] と表示される //配列を連結し、元の配列を置き換え var arrStr = arrStr.concat(arrStr2); console.log(arrStr); // Array(5) [ "aaaa", "bb", "ccccc", "111", "222" ] と表示される
配列の切出しを slice を使って行う例を以下に示します。配列の切出し
//配列の宣言 var arrStr = ["aaaa", "bb", "ccccc", "d", "eee" ]; console.log(arrStr); // Array(5) [ "aaaa", "bb", "ccccc", "d", "eee" ] と表示される //開始のみ指定 var arrStr2 = arrStr.slice(1); console.log(arrStr2); // Array(4) [ "bb", "ccccc", "d", "eee" ] と表示される //開始、終了指定 var arrStr3 = arrStr.slice(1, 4); console.log(arrStr3); // Array(3) [ "bb", "ccccc", "d" ] と表示される //開始、終了指定:終了が範囲を超えた指定 var arrStr4 = arrStr.slice(1, 10); console.log(arrStr4); // Array(4) [ "bb", "ccccc", "d", "eee" ] と表示される
配列の要素の入替を splice を使って行う例を以下に示します。配列の要素の入替
//配列の宣言 var arrStr = ["aaaa", "bb", "ccccc", "d", "eee" ]; console.log(arrStr); // Array(5) [ "aaaa", "bb", "ccccc", "d", "eee" ] と表示される //Index、削除個数、追加要素の指定 var arrStr2 = arrStr.splice(1, 2, "111", "22"); //元の配列の表示 console.log(arrStr); // Array(5) [ "aaaa", "bb", "111", "22", "d", "eee" ] と表示される //削除された配列の表示 console.log(arrStr2); // Array(2) [ "bb", "ccccc" ] と表示される
-
連想配列とは通常の配列の様に要素を指標によって参照するのではなく、キーとなる文字列とそれに対応する値を持ちます。 しかし、JavaScript では指標に文字列を指定できません。但し、 Array のプロパティとして取り扱うことで連想配列の様な振る舞いが可能です。
連想配列的宣言
//連想配列の宣言 var arrVar = { name: "test", value: "12345" }; console.log(arrVar); // Object { name: "test", value: "12345" } と表示される //個別の表示 console.log(arrVar["name"]); // test と表示される console.log(arrVar["value"]); // 12345 と表示される
上の例では arrVar クラスを配列の様に宣言し生成していますが、コンソールには Object と表示されます。 これはオブジェクトのプロパティであることが分かります。
それぞれのプロパティを個別に表示させると、連想配列的に値を返します。
また、以下の例の様に、宣言された連想配列に後から要素を追加することもできます。
連想配列的宣言と値の追加
//連想配列の宣言 var arrVar = { name: "test", value: "12345" }; //連想配列への要素追加 arrVar["item"] = "aaaaaaa"; console.log(arrVar); // Object { name: "test", value: "12345", item: "aaaaaaa" } と表示される
ここで連想配列と言っているものはオブジェクトであり、その中のプロパティを宣言してそれぞれをプロパティ名(キー名)によりアクセスします。 オブジェクトのプロパティへのアクセスはドットで連結することで行えます。以下に例を示します。
連想配列のプロパティへのアクセス
//連想配列の宣言 var arrVar = { name: "test", value: "12345" }; //連想配列の各要素へのアクセス(プロパティを指定) console.log(arrVar.name); // test と表示される console.log(arrVar.value); // 12345 と表示される //要素の追加 arrVar.item = "aaaa"; console.log(arrVar.item); // aaaa と表示される console.log(arrVar); // Object { name: "test", value: "12345", item: "aaaa" } と表示される
オブジェクトへのプロパティ追加は簡単にできるところが JavaScript の自由度を高めていると思います。 (逆に言えば、プログラムを難しくしているのかもしれませんが)
実はオブジェクトには関数も持つことが出来ます。以下の例は最初に宣言したオブジェクトに対して後から関数を追加しています。
連想配列への関数追加
//連想配列の宣言 var arrVar = { name: "test", value: "12345" }; //要素の追加 arrVar.item = "aaaa"; //関数の追加 arrVar.func = function() { alert("test"); // 単にメッセージで「test」の表示 } console.log(arrVar); // Object { name: "test", value: "12345", item: "aaaa", func: func() … } と表示される //関数の実行 arrVar.func(); // 「test」の表示が行われる
この関数は後から追加しなくても、最初の宣言で行えばもっと簡素にできます。
連想配列の関数宣言
//連想配列の宣言 var arrVar = { name: "test", value: "12345", item: "aaaa", func: function() { alert("test"); // メッセージで「test」の表示 } }; console.log(arrVar); // Object { name: "test", value: "12345", item: "aaaa", func: func() … } と表示される //関数の実行 arrVar.func(); // 「test」の表示が行われる
-
JavaScript でも当然ですが配列が使えます。VB.NETの配列と似たところがありますので、VB.NETを使っている方は特に問題無く理解ができます。 先ずは、配列の枠だけを宣言してみます。以下のソースでは空の配列を宣言し値を追加しています。
以下の処理で console.log を使用していますが、これによりブラウザのコンソール画面に変数の内容が表示されます。空の配列を宣言と値の追加
//空の配列宣言 var arrNum = new Array(); //未定義の指標での代入で追加 arrNum[0] = 100; arrNum[1] = 200; arrNum[2] = 300; console.log(arrNum); // Array(3) [ 100, 200, 300 ] と表示される
上の例では Array クラスを宣言し生成していますが以下の方法でも同じことが出来ます。
値の追加は配列のメソッド push を使って最後尾に追加しています。
空の配列を宣言と値の追加その2
//空の配列宣言 var arrNum = []; //配列のpush メソッドで配列の最後尾に追加する arrNum.push(100); arrNum.push(200); arrNum.push(300); console.log(arrNum); // Array(3) [ 100, 200, 300 ] と表示される
そこで、配列の初期化の方法ですが、上記の例の Array の括弧の中に要素をカンマ区切りで行えます。Arrayでの配列の初期化
//空の配列宣言 var arrNum = new Array(100, 200, 300); console.log(arrNum); // Array(3) [ 100, 200, 300 ] と表示される
[] の中にも同様にできます。こちらの方が簡単です。
配列の初期化では要素の指標が0(ゼロ)から振られますので注意が必要です。以下の例では配列の参照を行って合計の計算を行っています。[]での配列の初期化
//空の配列宣言 var arrNum = [100, 200, 300]; console.log(arrNum); // Array(3) [ 100, 200, 300 ] と表示される //配列の参照例としての合計計算 var sum = 0; for(i = 0; i < arrNum2.length; i++) { sum += arrNum2[i]; //指標は[0]から振られている } console.log(sum); // 600 と表示される
配列の要素は数値データとは限らず文字列を宣言することもできます。 以下の例は [] で要素が4個の文字列配列の初期化宣言を行っています。要素が文字列の配列の初期化
//配列宣言(単純な文字列配列) var arrStr = ["aaaa", "bb", "ccccc", "ddd"]; console.log(arrStr); // Array(4) [ "aaaa", "bb", "ccccc", "ddd" ] と表示される //配列内の文字列連結 var str = ""; for(i = 0; i < arrStr.length; i++) { str += arrStr[i]; } console.log(str); // aaaabbcccccddd と表示される
尚、配列の宣言で文字列と数値を混在させたものを宣言することが出来ます。 以下の例がそれですが、 arrMix の中身は混在していることが分かります。 文字列連結において文字列と数値の + 処理では数値が文字列に暗黙の変換が行われるため、結果が文字列になります。要素が文字列の配列の初期化
//配列宣言 var arrMix = ["aaaa", 222, "ccccc", 4444]; console.log(arrMix); // Array(4) [ "aaaa", 222, "ccccc", 4444 ] と表示される //配列内の文字列連結 var str = ""; for(i = 0; i < arrMix.length; i++) { str += arrMix[i]; // 数値が文字列に暗黙の変換 } console.log(str); // aaaa222ccccc4444 と表示される