みこむらめもむらむらむら

なんかHTML5とかJS勉強とかやりながらめもを綴るブログ

【JavaScript】すべてのオブジェクトのひな形(Objectオブジェクト)

Objectオブジェクトとは

Objectオブジェクトとは、オブジェクトの共通的な性質/機能を提供する
すべてのオブジェクトの基本オブジェクトである
組み込みオブジェクトもユーザ定義オブジェクトも
「オブジェクト」と名のつくものはすべて
Objectオブジェクトで定義されたプロパティやメソッドを
共通して利用することができる

Objectオブジェクトで利用可能なメンバ

  • constructor
  • toString()
    • オブジェクトの文字列表現を取得
  • valueOf()
    • オブジェクトの基本型表現(多くは数値)を取得
  • hasOwnProperty(prop)
    • 指定したプロパティを持つか
  • propertylsEnumerable(prop)
    • for..in命令によってプロパティ/メソッドを列挙できるか
  • isPrototypeOf(obj)
    • 呼び出し元のオブジェクトが指定したオブジェクトのプロトタイプであるか

オブジェクトを基本型に変換する(toString/valueOfメソッド)

toString/valueOfメソッドは
それぞれのオブジェクトの内容を基本型の値に変換する

  • toStringメソッド
    • 文字列を返す
  • valueOfメソッド
    • 文字列以外の値が返されることを「期待して」使われる
var obj = new Object();
document.writeln(obj.toString());  //[object Object]
document.writeln(obj.valueOf());  //[object Object]

var dat = new Date();
document.writeln(dat.toString());  //Wed Feb 01 2012 19:25:40 GMT+0900
document.writeln(dat.valueOf());  //1328091940780

var ary = ['red', 'blue', 'yellow'];
document.writeln(ary.toString());  //red,blue,yellow
document.writeln(ary.valueOf());  //red,blue,yellow

var num = 10;
document.writeln(num.toString());  //10
document.writeln(num.valueOf());  //10

var reg = /\d{3}-\d{4}/;
document.writeln(reg.toString());  ///\d{3}-\d{4}/g
document.writeln(reg.valueOf());  ///\d{3}-\d{4}/g

デフォルトのObjectオブジェクトは
toString/valueOfメソッドともに意味のある情報を返さない
もし自前のオブジェクトを定義する場合、
toString/valueOfメソッドが意味ある情報を返すように
自分でtoString/valueOfメソッドを
定義(上書き)する必要がある
(メソッドの定義方法は後述)

主な組み込みオブジェクトは基本的に
toString/valueOfメソッドともに同じ結果を返す
唯一Dateオブジェクトに関しては以下のように違う値を返す

  • toStringメソッド
    • 日付の文字列表現
  • valueOfメソッド
    • タイムスタンプ値(数値表現)

まちがいなくそうなってるね、うん

JavaScript
オブジェクトを文字列に変換する必要がある文脈では
自動的にtoStringメソッドを呼び出すため
document.writelnメソッド、+演算子などでは
明示的にtoStringメソッドをを呼び出さなくても
暗黙的に文字列表現に変換される、すてきね

インスタンスのオブジェクト型を判定する(constructorプロパティ)

変数のデータ型を判定するtypeof演算子は既に勉強したが
typeof演算子はあくまで基本型を識別することしかできない

というのも、参照型の値については
たとえばObject、Array、Dateオブジェクト
いずれインスタンスであってもtypeof演算子
一様に"object"としか返さないため

参照型(オブジェクト型)の変数を識別するには
constructorプロパティを使用する必要がある

var data = [];
if (typeof data == 'object' && data.constructor == Array){
  document.writeln('変数dataはArrayオブジェクトのインスタンスです');
  //変数dataはArrayオブジェクトのインスタンスです
}

厳密にはconstructorプロパティは戻り値として
インスタンスの生成に使用された
コンストラクタ(Functionオブジェクト)を返す
オブジェクト名(文字列)を返しているわけではない
よって

data.constructor == 'Array'

のようにクォートで括って文字列扱いしてはいけない

またconstructorプロパティと同等の機能を持つ演算子として
instanceof演算子も存在する
さっきの例をinstanceof演算子を利用して
下記のように書き換えることができる

if (typeof data == 'object' && data instanceof Array){

なるほどですねー

匿名オブジェクトを作成する

Objectオブジェクトは直接インスタンス化することで
ユーザが自前のオブジェクトを
定義するのに利用することができる

var obj = new Object();

このようなオブジェクトを
「独自のオブジェクト名を持たない」という意味で
匿名オブジェクト無名オブジェクトと呼ぶ
匿名オブジェクトは、作成した直後は
オブジェクト共通のプロパティ/メソッドの他は
何らデータを持たない、いうなれば空の状態
この空の器に対してデータ(つまりプロパティ)を追加するには
以下のような記述をする

obj.name = '石原 さとみ';
obj.birth = new Date(1986, 12, 24);
obj.old = 25;

さとみなのは私の趣味です
このように定義したプロパティは通常のプロパティと同様
ドット演算子でアクセスすることができる

document.writeln(obj.name);

匿名オブジェクトを利用すれば
その場限りしか使わず再利用することのないような
ちょっとしたデータを受け渡しする場合にも
いちいち後述するような「クラス」を定義する必要がないので
コードをシンプルに記述することができる
(たとえば「関数で複数の値を返したい」などという場合は
配列や匿名オブジェクトを利用すると便利)
ふむふむはあくしますた

プロパティだけでなくメソッドを定義することもできるが
そのために必要な関数の知識は後述する、とのことです
はーい!早く関数やりたい
一時的なデータの受け渡し目的で
利用することが多い匿名オブジェクトで
メソッドを指定する機会はあまり多くないはず

また、匿名オブジェクトを生成するために
Objectオブジェクトだけでなく、Array/Dateのような
既存の組み込みオブジェクトを利用することもできる
しかし、匿名オブジェクトを生成するために
これら特定の目的を持ったオブジェクトをベースにする理由はない
かえって間違いやバグのもととなる可能性があるため
通常はオブジェクトとして中性的な機能のみを持つ
Objectオブジェクトを使うべき
了解しましたー!

さらにさらに
本文の記述はリテラル表現をつかって書くこともできる

var obj = {name:'', birth: new Date(1986, 12, 24), old:25};

「オブジェクトリテラルでオブジェクトを生成する」というのは
「匿名オブジェクトを定義する」ことと同じ意味になる