オブジェクトについて(Object)
・ | Object クラスについて |
・ | オブジェクトを作成する |
・ | オブジェクトツリーを構築する |
・ | Object クラスのプロパティについて |
・ | Object クラスのメソッドについて |
・ | Object クラスのデータ管理について |
・ | オブジェクトを複製する |
・ | 参照(リファレンスデータ)について |
Object クラスについて
■Object クラスについて
Object クラスは、連想配列用のクラスです。
ユニーク(唯一)な文字列をキーにして、好きなデータを格納する事ができます。
Object クラスは、すべてのオブジェクトの原型となります。
■データ型の種類について
データの型には、プリミティブ型と、リファレンス型があります。
■プリミティブ型について
プリミティブ型は、基本的で単純なデータ型です。
null、undefined、Boolean、Number、String 型が該当します。
■リファレンス型について
リファレンス型は、複合的なデータ型です。
Object、Array、Function 型など、すべてのオブジェクトが該当します。
リファレンス型については、こちらで解説しています。
オブジェクトを作成する
■Object オブジェクトを作成する
new 演算子を使って、Object クラスをインスタンス化します。
通常は、引数を省略して下さい。
空の Object オブジェクトを作成することができます。
new Object ( 値情報 ) :Object
第01引数(略可) | * | オブジェクト内に値情報 [[PrimitiveValue]] を保有したい場合に指定。主にプリミティブデータを指定。 |
戻り値 | Object | Object オブジェクト |
■第01引数 (値情報)
任意の値情報を保有しているオブジェクトを作成したい場合に指定します。
指定したデータ型のコンストラクタ関数を使って、オブジェクトを作成した場合と同等です。
null や undefined 値を指定した場合、空の Object オブジェクトが作成されます。
数値型を指定して、オブジェクトを作成する
// ------------------------------------------------------------
// 数値型のデータを指定して、オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object(123);
// データ型を確認する(オブジェクトの一種である)
console.log(typeof(obj)); // "object"
// 値情報を取得する
console.log(obj.valueOf()); // 123
// 文字列情報を取得する
console.log(obj.toString()); // "123"
// ------------------------------------------------------------
// Number オブジェクトを作成する(数値型データの作成ではない)
// ------------------------------------------------------------
var obj = new Number(123);
// データ型を確認する(オブジェクトの一種である)
console.log(typeof(obj)); // "object"
// 値情報を取得する
console.log(obj.valueOf()); // 123
// 文字列情報を取得する
console.log(obj.toString()); // "123"
文字列型を指定して、オブジェクトを作成する
// ------------------------------------------------------------
// 文字列型のデータを指定して、オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object("あいうえお");
// データ型を確認する(オブジェクトの一種である)
console.log(typeof(obj)); // "object"
// 値情報を取得する
console.log(obj.valueOf()); // "あいうえお"
// 文字列情報を取得する
console.log(obj.toString()); // "あいうえお"
// ------------------------------------------------------------
// String オブジェクトを作成する(文字列型データの作成ではない)
// ------------------------------------------------------------
var obj = new String("あいうえお");
// データ型を確認する(オブジェクトの一種である)
console.log(typeof(obj)); // "object"
// 値情報を取得する
console.log(obj.valueOf()); // "あいうえお"
// 文字列情報を取得する
console.log(obj.toString()); // "あいうえお"
■空のオブジェクトを作成する
空のオブジェクトを作成する
// 空の Object オブジェクトを作成する
var obj = new Object();
// 出力テスト
console.log(obj);
■初期データを格納しつつ Object オブジェクトを作成する
■オブジェクトリテラルを使用する
中括弧 { } の中に、キー:データ と記述します。
キーに指定する名称は、変数の命名規則に従う必要があります。
複数のデータを格納したい場合は、カンマ , で区切ります。
この書式を、オブジェクトリテラルといいます。
空の Object オブジェクトを作成する
// 空の Object オブジェクトを作成する
var obj = { };
// 出力テスト
console.log(obj);
オブジェクトリテラルを使って、Object オブジェクトを作成する
// ------------------------------------------------------------
// オブジェクトリテラルを使って、Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = { aaaaa:null , bbbbb:true , ccccc:123 , ddddd:"あいうえお" };
// ------------------------------------------------------------
// 出力テスト(ドットアクセス演算子を使ってアクセス)
// ------------------------------------------------------------
console.log(obj.aaaaa); // null
console.log(obj.bbbbb); // false
console.log(obj.ccccc); // 123
console.log(obj.ddddd); // "あいうえお"
■キーをダブルクォーテーションで括った場合
キーは、ダブルクォーテーション "" で括ることができます。
キーをダブルクォーテーションで括った場合、変数の命名規則に従う必要はありません。
全角や数値などのすべての文字を、キーとして使用することができます。
オブジェクトリテラルを使って、Object オブジェクトを作成する(キーをダブルクォーテーションで括る)
// ------------------------------------------------------------
// オブジェクトリテラルを使って、Object オブジェクトを作成する
// ------------------------------------------------------------
var obj = { "添字1":null , "添字2":true , "添字3":123 , "添字4":"あいうえお" };
// ------------------------------------------------------------
// 出力テスト(配列アクセス演算子を使ってアクセス)
// ------------------------------------------------------------
console.log(obj["添字1"]); // null
console.log(obj["添字2"]); // false
console.log(obj["添字3"]); // 123
console.log(obj["添字4"]); // "あいうえお"
■プロトタイプを指定して、Object オブジェクトを作成する
Object.create() メソッドを使用します。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.create ( プロトタイプ , descriptors ) :Object
第01引数 | Object | プロトタイプとなるオブジェクトを指定。 |
第02引数(略可) | Object | 初期化用パラメータをオブジェクト形式で指定。(ディスクリプタの辞書) |
戻り値 | Object | 新しい Object オブジェクトが得られる。 |
■第01引数 (プロトタイプオブジェクト)
プロトタイプ(原型)となるオブジェクトを指定します。
デフォルト値を指定したい場合は、Object.prototype をセットします。
プロトタイプについては、こちらで解説しています。
コンストラクタ関数の、prototype プロパティにあるオブジェクトを指定する事ができます。
この場合、コンストラクタ関数を実行せずに、インスタンスを作成する事ができます。
コンストラクタ関数のプロトタイプを指定して、オブジェクトを作成した時の動作を確認する
// Object.create メソッドに対応している
if(Object.create){
// ------------------------------------------------------------
// MyFunc という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc(){
}
// ------------------------------------------------------------
// MyFunc のプロトタイプを指定して、オブジェクトを作成する
// ------------------------------------------------------------
var obj = Object.create(MyFunc.prototype);
// ------------------------------------------------------------
// オブジェクトのコンストラクタは、MyFunc であるか?(実際は MyFunc 関数は実行されていない)
// ------------------------------------------------------------
console.log(obj.constructor == MyFunc); // true
// ------------------------------------------------------------
// オブジェクトは、MyFunc コンストラクタを使って実体化されたか?(実際は MyFunc 関数は実行されていない)
// ------------------------------------------------------------
console.log(obj instanceof MyFunc); // true
// ------------------------------------------------------------
// 後から MyFunc 関数を手動的に実行して初期化できる
// ------------------------------------------------------------
MyFunc.call(obj);
}
■第02引数 (ディスクリプタの辞書)
初期化用のオブジェクトを作成します。
好きな名前のプロパティを追加し、ディスクリプタをセットします。
この名前は、設定したいプロパティの指名を意味します。
■ディスクリプタの設定
新しいオブジェクトを作成し、以下のプロパティを設定します。
プロパティ名 | 型 | 説明 | デフォルト |
value | * | セットする値を指定。 | undefined |
writable | Boolean | 書き込みアクセスを許可するか? | true |
enumerable | Boolean | 列挙される事を許可するか?(for..in 文など) | true |
configurable | Boolean | プロパティの削除を許可するか? | true |
get | Function | ゲッター用のコールバック関数を指定。 | |
set | Function | セッター用のコールバック関数を指定。 |
■作成例
Object.create メソッドを使って、空のオブジェクトを作成する
// Object.create メソッドに対応している
if(Object.create){
// 空の Object オブジェクトを作成する
var obj = Object.create(Object.prototype);
}
Object.create メソッドを使って、オブジェクトを作成する
// Object.create メソッドに対応している
if(Object.create){
// ------------------------------------------------------------
// 初期化用のパラメータを用意する
// ------------------------------------------------------------
var descriptors = {
aaa:{
// 値
value:true,
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
},
bbb:{
// 値
value:123,
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
},
ccc:{
// 値
value:"あいうえお",
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
}
};
// ------------------------------------------------------------
// プロトタイプ用オブジェクトを作成
// ------------------------------------------------------------
var prototype_obj = new Object();
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = Object.create(prototype_obj , descriptors);
// 出力テスト
console.log(obj); // aaa:true , bbb:123 , ccc:"あいうえお"
}
ゲッタとセッタの動作を確認する
// Object.create メソッドに対応している
if(Object.create){
// ------------------------------------------------------------
// 初期化用のパラメータを用意する
// ------------------------------------------------------------
var descriptors = {
aaa:(function(){
// ディスクリプタを作成
var descriptor = new Object();
// ローカル変数
var _variable_;
// ------------------------------------------------------------
// ゲッタ用コールバック関数
// ------------------------------------------------------------
descriptor.get = function (){
return _variable_;
};
// ------------------------------------------------------------
// セッタ用コールバック関数
// ------------------------------------------------------------
descriptor.set = function (v){
// 出力テスト
console.log("set:" + v);
_variable_ = v;
};
return descriptor;
})()
};
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = Object.create(Object.prototype , descriptors);
// 書き込みアクセス
obj.aaa = "書き込みテスト";
// 読み取りアクセス
var v = obj.aaa;
// 出力テスト
console.log("get:" + v); // "書き込みテスト"
}
■オブジェクトの任意のプロパティにアクセスする
ドットアクセス演算子か、配列アクセス演算子を使用します。
アクセスしたプロパティに、データが存在しない場合は、undefined 値が得られます。
■ドットアクセス演算子を使用する
ドットアクセス演算子は、Object.キー と記述します。
キーの名称は、変数の命名規則に従う必要があります。
ドットアクセス演算子を使って、任意のプロパティにアクセスする
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = {
aaaaa:null,
bbbbb:true,
ccccc:123,
ddddd:"あいうえお"
};
// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
// aaaaa プロパティからデータを取得
var v = obj.aaaaa;
// 出力テスト
console.log(v); // null
// ccccc プロパティからデータを取得
var v = obj.ccccc;
// 出力テスト
console.log(v); // 123
// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// bbbbb プロパティにデータをセット
obj.bbbbb = false;
// eeeee プロパティにデータをセット
obj.eeeee = "かきくけこ";
// 出力テスト
console.log(obj); // aaaaa:null , bbbbb:false , ccccc:123 , ddddd:"あいうえお" , eeeee:"かきくけこ"
■配列アクセス演算子を使用する
配列アクセス演算子は、Object["キー"] と記述します。
キーの名称は、変数の命名規則に従う必要はありません。
配列アクセス演算子を使用すると、プロパティ名の指定を動的に制御する事ができます。
配列アクセス演算子を使って、任意のプロパティにアクセスする
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = {
"添字1":null,
"添字2":true,
"添字3":123,
"添字4":"あいうえお"
};
// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
// "添字1" プロパティからデータを取得
var v = obj["添字1"];
// 出力テスト
console.log(v); // null
// "添字3" プロパティからデータを取得
var key = "添字3";
var v = obj[key];
// 出力テスト
console.log(v); // 123
// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// "添字2" プロパティにデータをセット
obj["添字2"] = false;
// "添字5" プロパティにデータをセット
var key = "添字5";
obj[key] = "かきくけこ";
// 出力テスト
console.log(obj); // "添字1":null , "添字2":false , "添字3":123 , "添字4":"あいうえお" , "添字5":"かきくけこ"
■オブジェクトのすべてのプロパティに順番にアクセスする
■ for..in 文を使用する
for..in 文を使って、アクセスする例です。
プロパティ名を取得できるので、配列アクセス演算子を使ってデータにアクセスします。
for..in 文を使用して、すべてのプロパティのデータに順番にアクセスする
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = {
aaa:null,
bbb:true,
ccc:123,
ddd:"あいうえお"
};
// ------------------------------------------------------------
// for..in 文を使用して、すべてのプロパティのデータに順番にアクセスする
// ------------------------------------------------------------
var key;
for (key in obj){
console.log("---");
console.log("key:" + key);
console.log("data:" + obj[key]);
}
■オブジェクトの任意のプロパティを削除する
delete 文を使用します。
オブジェクトの任意のプロパティを削除する
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = {
aaa:null,
bbb:true,
ccc:123,
ddd:"あいうえお"
};
// ------------------------------------------------------------
// オブジェクトの任意のプロパティを削除する
// ------------------------------------------------------------
// aaa プロパティを削除する
delete obj.aaa;
// ccc プロパティを削除する
delete obj["ccc"];
// ------------------------------------------------------------
// 残っているプロパティをすべて出力する
// ------------------------------------------------------------
var key;
for (key in obj){
console.log("---");
console.log("key:" + key);
console.log("data:" + obj[key]);
}
オブジェクトツリーを構築する
■オブジェクトツリーを構築する
■オブジェクトツリーを構築するには?
Object クラスは、連想配列用のクラスです。
Object オブジェクト1つだけでは、木構造の階層を構築する事はできません。
Object オブジェクトは、ノード(節)1つとして利用できます。
オブジェクトの各プロパティに、必要な数だけ Object オブジェクトを作成して格納します。
例えば、2段の階層を持つオブジェクトツリーを構築する例です。
オブジェクトツリーを構築するには、オブジェクトの各プロパティに Object オブジェクトを作成して格納する
// オブジェクトを作成する(ルートに相当)
var obj = new Object();
// オブジェクトの各プロパティに、オブジェクトを作成して格納する(ノードに相当)
obj.aaa = new Object();
obj.bbb = new Object();
obj.ccc = new Object();
■オブジェクトツリーを初期化する
オブジェクトツリーの初期化は、オブジェクトリテラルで記述すると、視覚的に見やすくなります。
オブジェクトリテラルを使って、複雑なオブジェクトツリーを構築する
var obj = {
aaa:{
count:123,
name:"テスト1",
result:false
},
bbb:{
count:456,
name:"テスト2",
result:true
},
ccc:{
count:789,
name:"テスト3",
param:{
ary:["a","b","c"],
name:"テスト4"
},
result:true
}
};
■オブジェクトツリー内の任意のプロパティにアクセスする
オブジェクトツリー内の任意のプロパティにアクセスするには、ドットアクセス演算子か、配列アクセス演算子を使用します。
2段の階層を持つオブジェクトツリーにアクセスする
// ------------------------------------------------------------
// 2段の階層を持つオブジェクトツリーを作成する
// ------------------------------------------------------------
// オブジェクトを作成する(ルートに相当)
var obj = new Object();
// オブジェクトの各プロパティに、オブジェクトを作成して格納する(ノードに相当)
obj.aaa = new Object();
obj.bbb = new Object();
obj.ccc = new Object();
// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// ドットアクセス演算子を使ってデータをセットする
obj.aaa.ddd = "D";
// 配列アクセス演算子を使ってデータをセットする
obj["ccc"]["eee"] = "E";
// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
// ドットアクセス演算子を使ってデータを取得する
var v = obj.aaa.ddd;
// 出力テスト
console.log(v); // "D"
//配列アクセス演算子を使ってデータを取得する
var v = obj["ccc"]["eee"];
// 出力テスト
console.log(v); // "E"
Object クラスのプロパティについて
■Object クラスのプロパティ
Object クラスには、以下のプロパティがあります。(一部抜粋)
プロパティ | 型 | 説明 |
constructor | Function | 自身が実体化された時に使われた、コンストラクタ関数を取得します。 |
__proto__ | Object | プロトタイプ(原型)オブジェクトにアクセスする。 |
■ constructor プロパティ
■コンストラクタ関数を使って、オブジェクトを生成する
こちらで解説しています。
■実体化に使われたコンストラクタ関数を取得する
constructor プロパティを使用します。
配列オブジェクトのコンストラクタ関数を調べる
// Array オブジェクトを作成する
var ary = new Array();
// コンストラクタ関数が一致するか調べる
console.log(ary.constructor == Array); // true
MyFunc オブジェクトのコンストラクタ関数を調べる
// ------------------------------------------------------------
// MyFunc という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc(){
}
// ------------------------------------------------------------
// MyFunc オブジェクトを作成する
// ------------------------------------------------------------
var obj = new MyFunc();
// コンストラクタ関数が一致するか調べる
console.log(obj.constructor == MyFunc); // true
■オブジェクトがプロトタイプチェーンである場合
constructor プロパティは、必ずしも正しい情報が得られるとは限りません。
constructor プロパティは、自身のオブジェクトが所有している訳ではありません。
コンストラクタ関数にデフォルトでセットされている、プロトタイプが所有しています。
prototype プロパティを変更してから、コンストラクタ関数を実体化した場合、自身の constructor プロパティの情報は失われている事に注意してください。
__proto__ プロパティを変更した場合も、自身の constructor プロパティの情報は失われます。
プロトタイプチェーンであるオブジェクトの constructor プロパティを調べる
// ------------------------------------------------------------
// MyFunc_A という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_A(){
}
// ------------------------------------------------------------
// MyFunc_B という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_B(){
}
// ------------------------------------------------------------
// 関数にデフォルトでセットされている、プロトタイプオブジェクトを取得する
// ------------------------------------------------------------
var prototype_a = MyFunc_A.prototype;
var prototype_b = MyFunc_B.prototype;
// 出力テスト
console.log(prototype_a.constructor === MyFunc_A); // true
console.log(prototype_b.constructor === MyFunc_B); // true
// ------------------------------------------------------------
// MyFunc_B オブジェクトを作成する(Object → MyFunc_B)
// ------------------------------------------------------------
var obj = new MyFunc_B();
// コンストラクタ関数が一致するか調べる
console.log(obj.constructor === MyFunc_B); // true
// ------------------------------------------------------------
// MyFunc_B 関数を実体化した時に、インスタンスのプロトタイプとなるオブジェクトを指定する
// ------------------------------------------------------------
MyFunc_B.prototype = new MyFunc_A();
// ------------------------------------------------------------
// MyFunc_B オブジェクトを作成する(Object → MyFunc_A → MyFunc_B)
// ------------------------------------------------------------
var obj = new MyFunc_B();
// コンストラクタ関数が一致するか調べる
console.log(obj.constructor === MyFunc_B); // false( MyFunc_B.prototype を変更したので本来の情報が失われた)
console.log(obj.constructor === MyFunc_A); // true (プロトタイプチェーンを巡って次に得られる情報)
■ __proto__ プロパティ
■プロトタイプについて
こちらで解説しています。
■プロトタイプ(原型)オブジェクトにアクセスする
__proto__ プロパティを使用します。
読み取りだけでなく、プロトタイプを変更する事も可能です。
このプロパティは、Internet Explorer 10 以前では、対応していません。
■使用例
コンストラクタ関数にセットされたプロトタイプとインスタンスのプロトタイプが一致するか調べる
var prototype_obj = Array.prototype;
// Array オブジェクトを作成する
var ary = new Array();
// プロトタイプが一致するか調べる
console.log(prototype_obj == ary.__proto__); // true
__proto__ プロパティを使って、プロトタイプチェーンを構築する
// ------------------------------------------------------------
// オブジェクトAを作成する
// ------------------------------------------------------------
var object_a = new Object();
object_a.aaa = "a";
// ------------------------------------------------------------
// オブジェクトBを作成する
// ------------------------------------------------------------
var object_b = new Object();
object_b.bbb = "b";
// ------------------------------------------------------------
// オブジェクトCを作成する
// ------------------------------------------------------------
var object_c = new Object();
object_c.ccc = "c";
// ------------------------------------------------------------
// オブジェクトBのプロトタイプに、オブジェクトAを指定
// ------------------------------------------------------------
object_b.__proto__ = object_a;
// ------------------------------------------------------------
// オブジェクトCのプロトタイプに、オブジェクトBを指定
// ------------------------------------------------------------
object_c.__proto__ = object_b;
// ------------------------------------------------------------
// 出力テスト (オブジェクトA → オブジェクトB → オブジェクトC)
// ------------------------------------------------------------
console.log(object_c.aaa); // "a"
console.log(object_c.bbb); // "b"
console.log(object_c.ccc); // "c"
Object クラスのメソッドについて
■Object クラスのメソッド
■ Object クラスのメソッド (一部抜粋)
メソッド | 説明 |
toString() | オブジェクトから文字列情報を取得する。 |
valueOf() | オブジェクトから値情報を取得する。 |
hasOwnProperty() | 指定したプロパティ名が存在するか調べる。 |
isPrototypeOf() | 自身が、指定オブジェクトのプロトタイプチェーン内に含まれるか調べる。 |
■ Object クラスの静的メソッド (一部抜粋)
メソッド | 説明 |
Object. | プロトタイプを指定して、オブジェクトを作成する。 |
Object. | ディスクリプタを使って、1つのプロパティを設定する。 |
Object. | ディスクリプタを使って、複数のプロパティを設定する。 |
Object. | プロパティ名を指定して、ディスクリプタを取得する。 |
Object. | プロパティ名をまとめて取得する。(すべて) |
Object. | プロパティ名をまとめて取得する。(列挙可能のみ) |
Object. | シンボルプロパティをまとめて取得する。 |
Object. | オブジェクトのプロトタイプを取得する。 |
メソッド | 説明 |
Object. | オブジェクトを拡張禁止に設定する。(追加が不可) |
Object. | オブジェクトを封印状態に設定する。(追加と削除が不可) |
Object. | オブジェクトを凍結状態に設定する。(追加と削除と書込が不可) |
Object. | 拡張可能状態であるか調べる。 |
Object. | 封印状態であるか調べる。 |
Object. | 凍結状態であるか調べる。 |
■オブジェクト内の値情報を、文字列形式で取得する
toString() メソッドを使用します。
Object.toString ( ) :String
引数 | Void | なし |
戻り値 | String | オブジェクト内の値情報 [[PrimitiveValue]] が、文字列形式で得られる |
■使用例
String オブジェクトから、文字列情報を取得する
// String オブジェクトを作成する
var obj = new Object("テスト");
// 出力テスト
console.log(obj.toString()); // "テスト"
日付オブジェクトから、文字列情報を取得する
// Date オブジェクトを作成する
var date_obj = new Date();
// 出力テスト
console.log(date_obj.toString());
■オーバーライドについて
toString() メソッドを、オーバーライドする事ができます。
toString プロパティを追加し、コールバック関数を登録します。
コールバック関数の戻り値から、好きな文字列を返します。
オブジェクトに値情報が存在しなかった場合、次に toString() メソッドが実行されます。
文字列型として読み取られる場合、直接 toString() メソッドが実行される事もあります。
toString メソッドをオーバーライドする
// ------------------------------------------------------------
// 空のオブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// valueOf メソッドをオーバーライドする
// ------------------------------------------------------------
obj.valueOf = function (){
alert("valueOf が呼び出された");
// 自身のオブジェクトを返した場合、値情報無しを意味する
return this;
};
// ------------------------------------------------------------
// toString メソッドをオーバーライドする
// ------------------------------------------------------------
obj.toString = function (){
alert("toString が呼び出された");
return "オーバーライド";
};
// ------------------------------------------------------------
// 文字列を足す(オブジェクトが読み取られる)
// ------------------------------------------------------------
var str = "" + obj;
// 出力テスト
console.log(str); // "オーバーライド"
■オブジェクト内の値情報を取得する
valueOf() メソッドを使用します。
Object.valueOf ( ) :*
引数 | Void | なし |
戻り値 | * | オブジェクト内の値情報 [[PrimitiveValue]] が得られる。 自身のオブジェクトが得られた場合は、値情報が無い事を意味する |
■使用例
Boolean オブジェクトから値情報を取得する
// Boolean オブジェクトを作成する
var obj = new Object(true);
// 出力テスト
console.log(obj.valueOf()); // true
Number オブジェクトから値情報を取得する
// Number オブジェクトを作成する
var obj = new Object(12345);
// 出力テスト
console.log(obj.valueOf()); // 12345
■オーバーライドについて
valueOf() メソッドを、オーバーライドする事ができます。
valueOf プロパティを追加し、コールバック関数を登録します。
コールバック関数の戻り値から、好きなデータを返します。
自身のオブジェクトを返した場合、値情報無しを意味します。
オブジェクトに、読み取りが試みられた場合、valueOf() メソッドが実行されます。
オーバーライドを終了する場合、delete 文を使って、valueOf プロパティを削除します。
valueOf メソッドをオーバーライドする
// ------------------------------------------------------------
// Number オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object(123);
// ------------------------------------------------------------
// valueOf メソッドをオーバーライドする
// ------------------------------------------------------------
obj.valueOf = function (){
alert("valueOf が呼び出された");
return 987;
};
// ------------------------------------------------------------
// 数値を足す(オブジェクトが読み取られる)
// ------------------------------------------------------------
var v = 0 + obj;
// 出力テスト
console.log(v); // 987
// ------------------------------------------------------------
// 数値として比較する(オブジェクトが読み取られる)
// ------------------------------------------------------------
if(obj > 0){
}
// ------------------------------------------------------------
// オーバーライドを終了する
// ------------------------------------------------------------
delete obj.valueOf;
■オブジェクトに、指定したプロパティ名が存在するか調べる
hasOwnProperty() メソッドを使用します。
Object.hasOwnProperty ( "プロパティ名" ) :Boolean
第01引数 | String | プロパティ名を文字列で指定 |
戻り値 | Boolean | プロパティが存在する場合 true、存在しない場合 false が得られる。 |
■使用例
指定したプロパティ名が存在するか調べる
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// プロパティを追加する
// ------------------------------------------------------------
obj.aaa = "VALUE";
obj.bbb = "VALUE";
// ------------------------------------------------------------
// 指定したプロパティ名が存在するか調べる
// ------------------------------------------------------------
var result0 = obj.hasOwnProperty( "aaa" );
var result1 = obj.hasOwnProperty( "bbb" );
var result2 = obj.hasOwnProperty( "ccc" );
// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log( result0 ); // true
console.log( result1 ); // true
console.log( result2 ); // false
■自身が、指定オブジェクトのプロトタイプチェーン内に含まれるか調べる
isPrototypeOf() メソッドを使用します。
このメソッドは、プロトタイプオブジェクトから呼び出します。
Object.isPrototypeOf ( オブジェクト ) :Boolean
第01引数 | Object | インスタンス側のオブジェクトを指定。 |
戻り値 | Boolean | 第01引数で指定したオブジェクトのプロトタイプチェーン内に、自身が存在するなら true |
■使用例
配列オブジェクトのプロトタイプを確認する
// ------------------------------------------------------------
// 配列オブジェクトを作成する
// ------------------------------------------------------------
var ary = new Array();
// ------------------------------------------------------------
// Array コンストラクタから、プロトタイプオブジェクトを取得する
// ------------------------------------------------------------
var prototype_obj = Array.prototype;
// ------------------------------------------------------------
// プロトタイプチェーンに含まれるか調べる
// ------------------------------------------------------------
var result = prototype_obj.isPrototypeOf( ary );
// 出力テスト
console.log(result); // true
プロトタイプチェーン状態にあるインスタンスのプロトタイプを確認する
// ------------------------------------------------------------
// MyFunc_A という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_A (){
}
// ------------------------------------------------------------
// MyFunc_B という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_B (){
}
// ------------------------------------------------------------
// MyFunc_C という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_C (){
}
// ------------------------------------------------------------
// プロトタイプチェーン関係を構築する
// ------------------------------------------------------------
// MyFunc_A オブジェクトを作成する
var obj_a = new MyFunc_A();
// MyFunc_B のプロトタイプにセットする
MyFunc_B.prototype = obj_a;
// MyFunc_B オブジェクトを作成する
var obj_b = new MyFunc_B();
// MyFunc_C のプロトタイプにセットする
MyFunc_C.prototype = obj_b;
// ------------------------------------------------------------
// MyFunc_C オブジェクトを作成する
// ------------------------------------------------------------
var obj_c = new MyFunc_C();
// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
console.log( obj_a.isPrototypeOf(obj_a) ); // false
console.log( obj_a.isPrototypeOf(obj_b) ); // true
console.log( obj_a.isPrototypeOf(obj_c) ); // true
console.log( obj_b.isPrototypeOf(obj_a) ); // false
console.log( obj_b.isPrototypeOf(obj_b) ); // false
console.log( obj_b.isPrototypeOf(obj_c) ); // true
console.log( obj_c.isPrototypeOf(obj_a) ); // false
console.log( obj_c.isPrototypeOf(obj_b) ); // false
console.log( obj_c.isPrototypeOf(obj_c) ); // false
■ディスクリプタを使って、1つのプロパティを設定する
Object.defineProperty() メソッドを使用します。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.defineProperty ( オブジェクト , "プロパティ名" , descriptor ) :Object
第01引数 | Object | オブジェクトを指定。 |
第02引数 | String | 追加したいインスタンス名を指定。 |
第03引数 | Object | 設定用オブジェクトを指定。(ディスクリプタ) |
戻り値 | Object | 第01引数で指定したオブジェクトが得られる。 |
■第03引数 (ディスクリプタ)
オブジェクトを作成し、以下のプロパティを設定します。
プロパティ名 | 型 | 説明 | デフォルト |
value | * | セットする値を指定。 | |
writable | Boolean | 書き込みアクセスを許可するか? | true |
enumerable | Boolean | 列挙される事を許可するか?(for..in 文など) | true |
configurable | Boolean | プロパティの削除を許可するか? | true |
get | Function | ゲッター用のコールバック関数を指定。 | |
set | Function | セッター用のコールバック関数を指定。 |
■追加例
ディスクリプタを使って、オブジェクトに1つのプロパティを追加する
// Object.defineProperty メソッドに対応している
if(Object.defineProperty){
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// 設定用オブジェクトを用意する
// ------------------------------------------------------------
var descriptor = {
// 値
value:"あいうえお",
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
};
// ------------------------------------------------------------
// オブジェクトに、aaa プロパティを追加する
// ------------------------------------------------------------
Object.defineProperty(obj , "aaa" , descriptor);
// 出力テスト
console.log(obj.aaa); // "あいうえお"
}
ゲッタとセッタの動作を確認する
// Object.defineProperty メソッドに対応している
if(Object.defineProperty){
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// 設定用オブジェクトを用意する
// ------------------------------------------------------------
var descriptor = (function(){
// ディスクリプタを作成
var self = new Object();
// ローカル変数
var _variable_;
// ------------------------------------------------------------
// ゲッタ用コールバック関数
// ------------------------------------------------------------
self.get = function (){
return _variable_;
};
// ------------------------------------------------------------
// セッタ用コールバック関数
// ------------------------------------------------------------
self.set = function (v){
// 出力テスト
console.log("set:" + v);
_variable_ = v;
};
return self;
})();
// ------------------------------------------------------------
// オブジェクトに、aaa プロパティを追加する
// ------------------------------------------------------------
Object.defineProperty(obj , "aaa" , descriptor);
// 書き込みアクセス
obj.aaa = "書き込みテスト";
// 読み取りアクセス
var v = obj.aaa;
// 出力テスト
console.log("get:" + v); // "書き込みテスト"
}
■ディスクリプタを使って、複数のプロパティを設定する
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.defineProperties ( オブジェクト , descriptors ) :Object
第01引数 | Object | オブジェクトを指定。 |
第02引数 | Object | 設定用オブジェクトを指定。(ディスクリプタの辞書) |
戻り値 | Object | 第01引数で指定したオブジェクトが得られる。 |
■第02引数 (ディスクリプタの辞書)
設定用のオブジェクトを作成します。
好きな名前のプロパティを追加し、ディスクリプタをセットします。
この名前は、設定したいプロパティの指名を意味します。
■ディスクリプタの設定
新しいオブジェクトを作成し、以下のプロパティを設定します。
プロパティ名 | 型 | 説明 | デフォルト |
value | * | セットする値を指定。 | |
writable | Boolean | 書き込みアクセスを許可するか? | true |
enumerable | Boolean | 列挙される事を許可するか?(for..in 文など) | true |
configurable | Boolean | プロパティの削除を許可するか? | true |
get | Function | ゲッター用のコールバック関数を指定。 | |
set | Function | セッター用のコールバック関数を指定。 |
■追加例
初期化用パラメータを指定して、オブジェクトに複数のプロパティを追加する
// Object.defineProperties メソッドに対応している
if(Object.defineProperties){
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// 設定用オブジェクトを用意する
// ------------------------------------------------------------
var descriptors = {
aaa:{
// 値
value:true,
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
},
bbb:{
// 値
value:123,
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
},
ccc:{
// 値
value:"あいうえお",
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
}
};
// ------------------------------------------------------------
// オブジェクトに、複数のプロパティを追加する
// ------------------------------------------------------------
Object.defineProperties(obj , descriptors);
// 出力テスト
console.log(obj); // aaa:true , bbb:123 , ccc:"あいうえお"
}
ゲッタとセッタの動作を確認する
// Object.defineProperties メソッドに対応している
if(Object.defineProperties){
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// 設定用オブジェクトを用意する
// ------------------------------------------------------------
var descriptors = {
aaa:(function(){
// ディスクリプタを作成
var descriptor = new Object();
// ローカル変数
var _variable_;
// ------------------------------------------------------------
// ゲッタ用コールバック関数
// ------------------------------------------------------------
descriptor.get = function (){
return _variable_;
};
// ------------------------------------------------------------
// セッタ用コールバック関数
// ------------------------------------------------------------
descriptor.set = function (v){
// 出力テスト
console.log("set:" + v);
_variable_ = v;
};
return descriptor;
})()
};
// ------------------------------------------------------------
// オブジェクトに、複数のプロパティを追加する
// ------------------------------------------------------------
Object.defineProperties(obj , descriptors);
// 書き込みアクセス
obj.aaa = "書き込みテスト";
// 読み取りアクセス
var v = obj.aaa;
// 出力テスト
console.log("get:" + v); // "書き込みテスト"
}
■プロパティ名を指定して、ディスクリプタオブジェクトを取得する
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.getOwnPropertyDescriptor ( オブジェクト , "プロパティ名" ) :Object
第01引数 | Object | オブジェクトを指定。 |
第02引数 | String | プロパティ名を指定。 |
戻り値 | Object | ディスクリプタオブジェクトが得られる。 |
■戻り値 (ディスクリプタ)
ディスクリプタオブジェクトには、以下のプロパティが存在します。
プロパティ名 | 型 | 説明 |
value | * | 現在の値を取得。 |
writable | Boolean | 書き込みアクセスを許可しているか |
enumerable | Boolean | 列挙される事を許可しているか?(for..in 文など) |
configurable | Boolean | プロパティの削除を許可しているか? |
get | Function | ゲッター用のコールバック関数を取得。 |
set | Function | セッター用のコールバック関数を取得。 |
■取得例
ディスクリプタオブジェクトを取得する
// Object.defineProperty メソッドに対応している
if(Object.defineProperty){
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// 設定用オブジェクトを用意する
// ------------------------------------------------------------
var descriptor0 = {
// 値
value:"あいうえお",
// 書き込みアクセスを許可するか?
writable:true,
// 列挙を許可するか?
enumerable:true,
// 削除を許可するか?
configurable:true
};
// ------------------------------------------------------------
// オブジェクトに、aaa プロパティを追加する
// ------------------------------------------------------------
Object.defineProperty(obj,"aaa" , descriptor0);
// ------------------------------------------------------------
// aaa プロパティのでぃスクリプトオブジェクトを取得する
// ------------------------------------------------------------
var descriptor1 = Object.getOwnPropertyDescriptor(obj , "aaa");
// 出力テスト
console.log(descriptor1); // value:"あいうえお" , writable:true , enumerable:true , configurable:true
}
■プロパティ名をまとめて取得する(すべて)
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.getOwnPropertyNames ( オブジェクト ) :Array
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Array | すべてのプロパティ名が、配列形式で得られる。 |
■検索範囲について
すべてのプロパティが、検索対象となります。
プロトタイプチェーンは、結果に含まれません。
■取得例
すべてのプロパティ名を、配列形式でまとめて取得する
// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// プロパティを追加する
// ------------------------------------------------------------
obj.aaa = "a";
obj.bbb = "b";
obj.ccc = "c";
// ------------------------------------------------------------
// Object.getOwnPropertyNames メソッドに対応している
// ------------------------------------------------------------
if(Object.getOwnPropertyNames){
// ------------------------------------------------------------
// すべてのプロパティ名を、配列形式でまとめて取得する
// ------------------------------------------------------------
var names = Object.getOwnPropertyNames(obj);
// 出力テスト
console.log(names); // ["aaa" , "bbb" , "ccc"]
}
■プロパティ名をまとめて取得する(列挙可能のみ)
Object.keys() メソッドを使用します。
ECMAScript 5 世代の機能です。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.keys ( オブジェクト ) :Array
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Array | 列挙可能なプロパティ名が、配列形式で得られる。 |
■検索範囲について
検索対象となるのは、列挙可能なプロパティのみです。
プロトタイプチェーンは、結果に含まれません。
for..in 文による列挙と同等です。
■取得例
列挙可能なプロパティ名を、配列形式でまとめて取得する
// Object.create メソッドに対応している
if(Object.create){
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = Object.create(Object.prototype,{
aaa:{ value:"a", enumerable:true },
bbb:{ value:"b", enumerable:false },
ccc:{ value:"c", enumerable:true },
ddd:{ value:"d", enumerable:true },
eee:{ value:"e", enumerable:false }
});
// ------------------------------------------------------------
// 列挙可能なプロパティ名を、配列形式でまとめて取得する
// ------------------------------------------------------------
var names = Object.keys(obj);
// 出力テスト
console.log(names); // ["aaa" , "ccc" , "ddd"]
}
■指定したオブジェクトから、プロトタイプを取得する
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.getPrototypeOf( オブジェクト ) :Object
第01引数 | Object | インスタンスオブジェクトを指定。 |
戻り値 | Object | プロトタイプオブジェクトが得られる。 |
■プロトタイプについて
こちらで解説しています。
■プロトタイプの変更について
__proto__ プロパティからアクセスする方法もあります。
読み取りだけでなく、変更も可能です。
■取得例
配列オブジェクトのプロトタイプを確認する
// 配列オブジェクトを作成
var ary = new Array();
// Object.getPrototypeOf メソッドに対応している
if(Object.getPrototypeOf){
// プロトタイプオブジェクトを取得
var prototype_obj = Object.getPrototypeOf( ary );
// 出力テスト
console.log(Array.prototype == prototype_obj); // true
}
コンストラクタ関数を実体化して作成したオブジェクトから、プロトタイプを取得する
// ------------------------------------------------------------
// MyFunc という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc(){
}
// ------------------------------------------------------------
// プロトタイプ用オブジェクトを作成
// ------------------------------------------------------------
var prototype_obj = new Object();
// ------------------------------------------------------------
// MyFunc 関数を実体化した時に、インスタンスのプロトタイプとなるオブジェクトを指定する
// ------------------------------------------------------------
MyFunc.prototype = prototype_obj;
// ------------------------------------------------------------
// MyFunc オブジェクトを作成
// ------------------------------------------------------------
var obj = new MyFunc();
// ------------------------------------------------------------
// Object.getPrototypeOf メソッドに対応している
// ------------------------------------------------------------
if(Object.getPrototypeOf){
// ------------------------------------------------------------
// オブジェクトからプロトタイプを取得し、一致するか調べる
// ------------------------------------------------------------
console.log(Object.getPrototypeOf( obj ) == prototype_obj); // true
}
■オブジェクトを拡張禁止に設定する
拡張禁止状態から、通常の状態に戻す事はできません。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.preventExtensions( オブジェクト ) :Object
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Object | 第01引数で指定したオブジェクトが得られる。 |
■拡張禁止状態について
拡張を禁止すると、プロパティの追加は不可能になります。
削除と書込と読取は可能です。
■設定例
オブジェクトの拡張を禁止する
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// ○ プロパティを追加する(この時点では拡張可能)
// ------------------------------------------------------------
obj.aaa = 0;
obj.bbb = 1;
// ------------------------------------------------------------
// Object.preventExtensions メソッドに対応している
// ------------------------------------------------------------
if(Object.preventExtensions){
// ------------------------------------------------------------
// オブジェクトの拡張を禁止する
// ------------------------------------------------------------
Object.preventExtensions( obj );
}
// ------------------------------------------------------------
// × プロパティを追加する(この時点では拡張禁止)
// ------------------------------------------------------------
obj.ccc = 2;
obj.ddd = 3;
// 出力テスト
console.log(obj); // aaa:0 , bbb:1
■オブジェクトを封印状態に設定する
Object.seal() メソッドを使用します。
封印状態を解除する事はできません。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.seal( オブジェクト ) :Object
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Object | 第01引数で指定したオブジェクトが得られる。 |
■封印状態について
オブジェクトを封印すると、プロパティの追加と削除は不可能になります。
書込と読取は可能です。
■設定例
オブジェクトを封印状態に設定する
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// ○ プロパティを追加する(この時点では通常)
// ------------------------------------------------------------
obj.aaa = 0;
obj.bbb = 1;
// ------------------------------------------------------------
// Object.seal メソッドに対応している
// ------------------------------------------------------------
if(Object.seal){
// ------------------------------------------------------------
// オブジェクトを封印状態に設定する
// ------------------------------------------------------------
Object.seal( obj );
}
// ------------------------------------------------------------
// × プロパティを削除する(この時点では封印状態)
// ------------------------------------------------------------
delete obj.aaa;
delete obj.bbb;
// ------------------------------------------------------------
// × プロパティを追加する(この時点では封印状態)
// ------------------------------------------------------------
obj.ccc = 2;
obj.ddd = 3;
// 出力テスト
console.log(obj); // aaa:0 , bbb:1
■オブジェクトを凍結状態に設定する
Object.freeze() メソッドを使用します。
凍結状態を解除する事はできません。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.freeze( オブジェクト ) :Object
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Object | 第01引数で指定したオブジェクトが得られる。 |
■凍結状態について
オブジェクトを凍結すると、プロパティの追加と削除と書込は不可能になります。
読取は可能です。
■設定例
オブジェクトを凍結状態に設定する
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// ------------------------------------------------------------
// ○ プロパティを追加する(この時点では通常)
// ------------------------------------------------------------
obj.aaa = 0;
obj.bbb = 1;
// ------------------------------------------------------------
// Object.freeze メソッドに対応している
// ------------------------------------------------------------
if(Object.freeze){
// ------------------------------------------------------------
// オブジェクトを凍結状態に設定する
// ------------------------------------------------------------
Object.freeze( obj );
}
// ------------------------------------------------------------
// × プロパティに書き込みアクセス(この時点では凍結状態)
// ------------------------------------------------------------
obj.aaa = "a";
obj.bbb = "b";
// ------------------------------------------------------------
// × プロパティを削除する(この時点では凍結状態)
// ------------------------------------------------------------
delete obj.aaa;
delete obj.bbb;
// ------------------------------------------------------------
// × プロパティを追加する(この時点では凍結状態)
// ------------------------------------------------------------
obj.ccc = 2;
obj.ddd = 3;
// 出力テスト
console.log(obj); // aaa:0 , bbb:1
■オブジェクトが拡張可能であるか調べる
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.isExtensible( オブジェクト ) :Boolean
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Boolean | 拡張禁止状態であれば、false が得られる。通常なら true が得られる。 |
■戻り値(拡張可能であるか)
true が得られた場合、通常のオブジェクトです。
false が得られた場合、拡張禁止状態です。
■オブジェクトを拡張禁止に設定する
Object.preventExtensions() メソッドを使用します。
■取得例
オブジェクトが拡張可能状態であるか調べる
// Object.preventExtensions メソッドに対応している
if(Object.preventExtensions){
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// 出力テスト
console.log(Object.isExtensible( obj )); // true
// ------------------------------------------------------------
// オブジェクトを拡張禁止状態に設定する
// ------------------------------------------------------------
Object.preventExtensions( obj );
// 出力テスト
console.log(Object.isExtensible( obj )); // false
}
■オブジェクトが封印状態であるか調べる
Object.isSealed() メソッドを使用します。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.isSealed( オブジェクト ) :Boolean
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Boolean | 封印状態であれば、true が得られる。 |
■封印状態とは?
こちらで解説しています。
■オブジェクトを封印状態に設定する
Object.seal() メソッドを使用します。
■取得例
オブジェクトが封印状態であるか調べる
// Object.seal メソッドに対応している
if(Object.seal){
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// 出力テスト
console.log(Object.isSealed( obj )); // false
// ------------------------------------------------------------
// オブジェクトを封印状態に設定する
// ------------------------------------------------------------
Object.seal( obj );
// 出力テスト
console.log(Object.isSealed( obj )); // true
}
■オブジェクトが凍結状態であるか調べる
Object.isFrozen() メソッドを使用します。
このメソッドは、InternetExplorer 8 以前では、対応していません。
Object.isFrozen( オブジェクト ) :Boolean
第01引数 | Object | オブジェクトを指定。 |
戻り値 | Boolean | 凍結状態であれば、true が得られる。 |
■凍結状態とは?
こちらで解説しています。
■オブジェクトを凍結状態に設定する
Object.freeze() メソッドを使用します。
■取得例
オブジェクトが凍結状態であるか調べる
// Object.freeze メソッドに対応している
if(Object.freeze){
// ------------------------------------------------------------
// オブジェクトを作成
// ------------------------------------------------------------
var obj = new Object();
// 出力テスト
console.log(Object.isFrozen( obj )); // false
// ------------------------------------------------------------
// オブジェクトを凍結状態に設定する
// ------------------------------------------------------------
Object.freeze( obj );
// 出力テスト
console.log(Object.isFrozen( obj )); // true
}
Object クラスのデータ管理について
■Object オブジェクトを辞書として使用する
Object オブジェクトは、文字列をキーとした辞書として取り扱う事ができます。
■辞書として取り扱う理由
Object オブジェクトは、内部でハッシュテーブルを使った高速化が実現されています。
文字列をキーとして指定することで、該当するデータを高速で検索する事ができます。
また、すべてのデータの中から該当するデータが存在しない事を、高速で判別する事もできます。
データの総数が、100 万以上ある場合でも、瞬時に検索できます。
■辞書として管理するためには?
データごとに、ユニーク(唯一)な識別名が、存在している必要があります。
例えば、以下の様なアドレス情報は、辞書として管理することができます。
辞書として管理するためには、データごとにユニークな識別名が必要
var page_a = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };
var page_x = { url:"http://example.com/x.html", title:"×××××", size:9999 };
var page_y = { url:"http://example.com/y.html", title:"×××××", size:9999 };
var page_z = { url:"http://example.com/z.html", title:"×××××", size:9999 };
■辞書を作成する
辞書として取り扱うための、Object オブジェクトを 1 つ作成します。
辞書用 Object オブジェクトを作成する
// 辞書を作成
var dictionary = new Object();
■辞書に既にデータが存在するか調べる
指定したプロパティに、すでにデータが存在するか調べます。
配列アクセス演算子を使って、調べたいプロパティにアクセスします。
結果が、真であればデータが存在します。偽であればデータは存在しません。
辞書に既にデータが存在するか調べる
// 辞書を作成
var dictionary = new Object();
// 検索したいアドレス情報
var url = "http://example.com/b.html";
// 辞書に既にデータが存在するか調べる
if(dictionary[url]){
console.log("データは存在する");
}else{
console.log("データは存在しない");
}
■辞書にデータを登録する
任意のプロパティに、データを登録します。
配列アクセス演算子を使って、任意のプロパティにデータを格納します。
辞書にデータを登録する
// 辞書を作成
var dictionary = new Object();
// 管理したいデータ
var page_b = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
// 辞書にデータが存在しないか調べる
if(!dictionary[page_b.url]){
// 辞書に新しいデータを登録する
dictionary[page_b.url] = page_b;
}
■辞書からデータを取得する
任意のプロパティから、データを取得します。
配列アクセス演算子を使って、任意のプロパティからデータを取得します。
undefined 値が得られる場合、データは存在しません。
辞書からデータを取得する
// 辞書を作成
var dictionary = new Object();
// 管理したいデータ
var page_a = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };
// 辞書にデータを登録する
dictionary[page_a.url] = page_a;
dictionary[page_b.url] = page_b;
dictionary[page_c.url] = page_c;
// 検索したいアドレス情報
var url = "http://example.com/a.html";
// 辞書からデータを取得する
var page = dictionary[url];
■辞書に登録したデータを削除する
任意のプロパティから、データを削除します。
delete 文を使って、任意のプロパティを削除します。
辞書に登録したデータを削除する
// 辞書を作成
var dictionary = new Object();
// 管理したいデータ
var page_a = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };
// 辞書にデータを登録する
dictionary[page_a.url] = page_a;
dictionary[page_b.url] = page_b;
dictionary[page_c.url] = page_c;
// 検索したいアドレス情報
var url = "http://example.com/a.html";
// 辞書からデータを取得する
var page = dictionary[url];
if(page){
// 辞書に登録したデータを削除する
delete dictionary[page.url];
}
オブジェクトを複製する
■オブジェクトを複製する
オブジェクトツリーを複製する関数です。
null、undefined、Boolean、Number、String、Array、Object 型のデータのみで構成する必要があります。
オブジェクトを複製する関数
// ------------------------------------------------------------
// オブジェクトを複製する関数
// ------------------------------------------------------------
function ObjectClone(obj){
if(obj === null) return null;
if(typeof(obj) != "object") return obj;
var s;
var o;
var k;
var r = new (obj.constructor)();
var q = new Array();
q.push({o:r,s:obj});
while(true){
k = q.pop();
if(!k) break;
o = k.o;
s = k.s;
for(k in s){
if(typeof(s[k]) == "object"){
if(s[k]){
o[k] = new (s[k].constructor)();
q.push({o:o[k],s:s[k]});
continue;
}
}
o[k] = s[k];
}
}
return r;
}
■使用例
オブジェクトツリーを複製する
// ------------------------------------------------------------
// オブジェクトを複製する関数
// ------------------------------------------------------------
function ObjectClone(obj){
if(obj === null) return null;
if(typeof(obj) != "object") return obj;
var s;
var o;
var k;
var r = new (obj.constructor)();
var q = new Array();
q.push({o:r,s:obj});
while(true){
k = q.pop();
if(!k) break;
o = k.o;
s = k.s;
for(k in s){
if(typeof(s[k]) == "object"){
if(s[k]){
o[k] = new (s[k].constructor)();
q.push({o:o[k],s:s[k]});
continue;
}
}
o[k] = s[k];
}
}
return r;
}
// ------------------------------------------------------------
// オブジェクトツリーを作成
// ------------------------------------------------------------
var obj = {
aaa:{
count:123,
name:"テスト1",
result:false
},
bbb:{
count:456,
name:"テスト2",
result:true
},
ccc:{
count:789,
name:"テスト3",
param:{
ary:["a","b","c"],
name:"テスト4"
},
result:true
}
};
// ------------------------------------------------------------
// オブジェクトを複製
// ------------------------------------------------------------
var clone = ObjectClone(obj);
// 出力テスト
console.log(clone);
参照(リファレンスデータ)について
■リファレンス型について
すべてのオブジェクトは、リファレンス型に該当します。
リファレンス型は、複合的なデータ型です。
Array、Object、Function 型などは、すべてリファレンス型です。
リファレンスは、参照を意味します。
オブジェクトが、どのように参照として動作するか確認してみます。
■オブジェクトの参照を確認する
1.配列を作成してみる
配列を作成して、「変数 ary0 」に格納してみます。
配列を作成する
// 配列を作成する
var ary0 = ["a","b","c"];
2.配列を別の変数に代入してみる
「変数 ary0 」の中身を、「変数 ary1 」に代入してみます。
デバッガでは、以下のように表示されました。
「変数 ary0 」の配列が、「変数 ary1 」へとコピーされているように見えます。
作成した配列オブジェクトを別の変数に代入する
// 配列を作成する
var ary0 = ["a","b","c"];
// 配列を別の変数に代入する
var ary1 = ary0;
3.片方の変数から配列に書き込んでみる
次に、「変数 ary1 」から、配列の一部を書き換えてみます。
デバッガで確認すると、「変数 ary0 」と「変数 ary1 」の両方の配列が変化しました。
内部でどのような処理が行われているのでしょうか。
片方の変数から、配列の一部を変更する
// 配列を作成する
var ary0 = ["a","b","c"];
// 配列を別の変数に代入する
var ary1 = ary0;
// 変数 ary1 から、配列の 0 番地を変更する
ary1[0] = "d";
■オブジェクトの本体と参照について
先ほど、配列オブジェクトを作成して、「変数 ary0 」に格納しました。
配列を作成する
// 配列を作成する
var ary0 = ["a","b","c"];
オブジェクトを作成すると、オブジェクトの本体は、メモリ上のどこかに生成されます。
「変数 ary0 」には、「メモリ上のどこかに存在するオブジェクト本体」へアクセスするための、参照データが格納されています。
配列オブジェクト本体が、「変数 ary0 」に、直接格納される訳ではありません。
■オブジェクトの参照渡しについて
先ほど、「変数 ary0 」の中身を「変数 ary1 」に代入しました。
このとき、「変数 ary0 」の配列が、「変数 ary1 」へとコピーされた訳ではありません。
作成した配列オブジェクトを別の変数に代入する
// 配列を作成する
var ary0 = ["a","b","c"];
// 配列を別の変数に代入する
var ary1 = ary0;
「変数 ary0 」から「変数 ary1 」に渡したのは、「メモリ上のどこかに存在するオブジェクト本体」へアクセスするための、参照データです。
これにより、「変数 ary1 」からも、配列オブジェクト本体へアクセスできるようになります。
■参照渡しについて
リファレンス型のデータを、別の変数に代入する事を、参照渡しと言います。
参照渡しを利用すると、複数の変数から、1つのオブジェクト本体を共有できるようになります。
■不要になったオブジェクト本体を解放する
オブジェクト本体を、直接的に消滅させる命令はありません。
delete 文は、オブジェクトを破棄する命令ではありません。( C++ 使いの方は注意)
オブジェクトが不要になった場合、オブジェクトを格納している変数を、別の値で上書きします。
基本的には、null 値をセットします。
配列オブジェクトを解放する
// 配列を作成する
var ary0 = ["a","b","c"];
// 変数に null 値をセットする(配列オブジェクト本体にアクセスする手段が失われる)
ary0 = null;
オブジェクトの参照データを、別の値で上書きしたので、「メモリ上のどこかに存在するオブジェクト本体」へアクセスする手段が失われる事になります。
このとき、ガベージコレクションが、自動的に物理メモリから解放します。
■ null 値について
null 値とは、リファレンス型のデータが存在しない事を意味します。偽となります。
何らかのリファレンス型のデータが存在する場合は、真となります。
■ガベージコレクションについて
ガベージコレクションは、ブラウザから、自動的に、不定期に発生します。
ガベージコレクションを、手動的に動作させる事はできません。
ガベージコレクションは、不要になったオブジェクト本体が、物理メモリ上に存在するか調べます。
不要なオブジェクト本体があれば、物理メモリから解放します。
■不要なオブジェクトを解放するためには?
アクセスする手段が失われたオブジェクト本体は、不要なオブジェクトと判別されます。
オブジェクトが不要になった場合、参照をすべて断つ必要があります。
不要なオブジェクトが格納されている変数があれば、別の値で上書きします。
Object オブジェクトを解放する
// オブジェクトを作成する
var obj0 = {a:0,b:1,c:2};
// オブジェクトの参照を別の変数に渡す
var obj1 = obj0;
// 変数に null 値をセットする(この時点では、obj1 からオブジェクト本体にアクセスできる為、消滅しない)
obj0 = null;
// 変数に null 値をセットする(この時点で、オブジェクト本体にアクセスする手段が失われた為、ガベージコレクションの対象となる)
obj1 = null;
■メモリリークについて
オブジェクトが不要になった場合、オブジェクトの参照をすべて断つ必要があります。
1つでも参照が残っている場合、永遠に解放されずに物理メモリに残り続けます。
解放漏れの不備により、ゴミが物理メモリを占有し続ける事を、メモリリークといいます。
■エージングテスト
一連の処理を、自動的に、繰り返し実行されるようにして、長時間放置します。
ブラウザがクラッシュしていないか、エラーが発生していないか、物理メモリの使用量が増え続けていないか、異常な動作をしていないかを確認します。
長時間の稼動に耐えるほど、安心できます。
■ DOM オブジェクトの解放について
DOM オブジェクトが、ノードリストを通じてドキュメントと繋がっている場合、自動的に解放される事はありません。
ドキュメントから、ノードリストを巡って、DOM オブジェクトへアクセスできる為です。