JavaScript

Objects Ⅰ

29 May 2014

オブジェクトとは何か?

オブジェクトは、現実世界の物や(人や銀行口座のような)実体を コードで表すことができ、関連のある情報を一まとめに保持しているもの

オブジェクトを作るには

varオブジェクト名=

var Takeshi = {};//情報を持っていないオブジェクト

プロパティ

オブジェクトに含める各々の情報のことをプロパティと呼びます。

プロパティには名前と値があります。 name : value

Takeshiの年齢(age)は 40才ならば age : 40

var Spencer = {
  age: 22,
  country: "United States"
};

var Me = {
  age: 40,
  country: "Japan"
};

プロパティにアクセスするには

dot notation

オブジェクト名 + . + プロパティ名

var myAge = Me.age;
var myCountry = Me.country;

bracket notation

オブジェクト名["プロパティ名"]

var myAge = Me["age"];
var myCountry = Me["country"];

別の作成方法

{ } を使ってオブジェクトを作成する記法を

literal notation といいます。

もう一つは、キーワード new を使う方法で

constructor を使いオブジェクトを作成する記法 ( constructor notation )として知られています。

new に続き Object() を記述し、空のオブジェクトを作ります。

var objectName = new Object();

この場合のプロパティの追加方法は

objectName.propertyName = value;

var bob = new Object();
bob.name = "Bob Smith";
bob.age = 30;

// literal notation
var susan1 = {
  name: "Susan Jordan",
  age: 24
};
// constructor notation
var susan2 = new Object();
susan2.name = "Susan Jordan";
susan2.age = 24;

メソッド

プロパティがオブジェクトに関連した変数と考えられます。

メソッド はオブジェクトに関連した関数と言えます。

var bob = new Object();
bob.name = "Bob Smith";
bob.age = 30;
// method, setAge
bob.setAge = function (newAge){
  bob.age = newAge;
};
// bobの歳を20にセットする
bob.setAge(20);

メソッド setAge の定義は、プロパティの定義に似ています。

大きな違いは、右辺に値ではなく関数を記述するところです。

このメソッドは、与えられた引数で、プロパティ bob.age を設定します。

// method, setAge
bob.setAge = function (newAge){
  bob.age = newAge;
};

メソッドの呼び出しは関数と同じようにします。

ObjectName.methodName()

// bobの歳を20にセットする
bob.setAge(20);

メソッドが重要な訳

var bob = new Object();
bob.age = 30;
// method, setAge
bob.setAge = function (newAge){
  bob.age = newAge;
};
// method getYearOfBirth 
bob.getYearOfBirth = function () {
  return 2012 - bob.age;//プロパティを使用
};

キーワード this

今までの setAge は, bob にとって bob.age を変更してくれるのでよかったのです。

しかし、ほかの人にもこのメソッドを利用したい時にはどうすればよいでしょうか。

新しいキーワード this を使い、多くのオブジェクトでメソッドが動作するようにします。

this は、プレースホルダーの役をして、 メソッドが実際に使われた時に、そのメソッドを呼び出したオブジェクトを指し示します。

bob.setAge(50) が呼ばれると、メソッド setAge の中の this は オブジェクト bob を指しているので this.agebob.age ということになります。

これで他のオブジェクトでも、一度定義したメソッドを再利用できます。

// bobを作成する前に"this"を使ってメソッドを定義します
var setAge = function (newAge) {
  this.age = newAge;
};
// bobを作ります
var bob = new Object();

// bobのプロパティ aga を設定
bob.age = 30;

// すでに作ったメソッドで、bobのメソッドを設定します
bob.setAge = setAge;
  
// bobの age を 50に変えます(メソッドの実行)
bob.setAge(50);

// susanを作成し age を 25 にする
var susan = new Object();
susan.age = 25;
//定義済みメソッドを再使用しsusanに設定する
susan.setAge = setAge;
// Susanの age を 35 にする
susan.setAge(35);

別種のメソッド

オブジェクト square を作ります。

正方形の1辺の長さを表すプロパティ sideLength を追加します。

周囲の長さを計算するメソッド calcPerimeter を追加します。

このメソッドは関数と同じように return で戻り値を受け取れます。

var square = new Object();
square.sideLength = 6;
square.calcPerimeter = function() {
  return this.sideLength * 4;
};
// 面積を計算するメッソッドを追加
square.calcArea = function() {
  return this.sideLength * this.sideLength;   
};

var p = square.calcPerimeter();

コンストラクタ

オブジェクト コンストラクタ

bob = new Object( ) と書いた場合

Object という組込みコンストラクタを使っています。

このコンストラクタはJavaScript言語にすでに定義されていて、 プロパティもメソッドないオブジェクトを作るだけです。

これは、その都度プロパティを追加しなければいけないことを意味しています。

カスタム コンストラクタ

オブジェクトごとに毎度毎度プロパティを追加するのは面倒なことです。

そんな object コンストラクタを使う代わりに プロパティを持った独自のコンストラクタを作ることができます。

Person というコンストラクタは Person オブジェクトを作るために使われます。

またキーワード thisを使って プロパティ nameage を定義し、与えられた引数の値にセットされます。

このコンストラクタを使って bobsusan を作ります。

//独自のコンストラクタ
function Person(name,age) {
  this.name = name;
  this.age = age;
}

// 独自のコンストラクタを使って bob と susan を作ります
var bob = new Person("Bob Smith", 30);
var susan = new Person("Susan Jordan", 25);

更なるオプション

すべてのプロパティを引数を使って定義する必要はありません。

今度のコンストラクタ Person では、 species が "Homo Sapiens" に設定されています。

このことは、どの Person を作る時も species は "Homo Sapiens" になるということです。

function Person(name,age) {
  this.name = name;
  this.age = age;
  this.species = "Homo Sapiens";
}

var sally = new Person("Sally Bowles",39);
var holden = new Person("Holden Caulfield",16);

Constructors With Methods

コンストラクタにプロパティを設定できるのに加えて、 メソッドを定義することもできます。つまり、オブジェクトを作成した段階で 独自のメソッドも持っているということです。

Rectangle コンストラクタにはプロパティ length, width があります。

そして、 calcArea, calcPerimeter メソッドがり、面積と周囲の長さを返します。

function Rectangle(length, width) {
  // own properties
  this.length = length;
  this.width = width;

  //own methods
  this.calcArea = function() {
      return this.length * this.width;
  };
  this.calcPerimeter = function() {
    return this.length * 2 + this.width * 2;  
  };
}

var rex = new Rectangle(7,3);
var area = rex.calcArea();
var perimeter = rex.calcPerimeter();

ほかのツールとオブジェクトを組み合わせる

オブジェクトの配列

オブジェクトは数値型や文字列型と同じように1種の型です。 なので、オブジェクトの配列を作ることができます。

// Person constructor
function Person (name, age) {
    this.name = name;
    this.age = age;
}

// an array of people : family
var family = new Array();
family[0] = new Person("alice", 40);
family[1] = new Person("bob", 42);
family[2] = new Person("michelle", 8);
family[3] = new Person("timmy",6);

ループ

数値や文字列の配列と同様に、ループでオブジェクトの配列を使用できます。

// Person constructor
function Person (name, age) {
    this.name = name;
    this.age = age;
}

// an array of people : family
var family = new Array();
family[0] = new Person("alice", 40);
family[1] = new Person("bob", 42);
family[2] = new Person("michelle", 8);
family[3] = new Person("timmy",6);

for (i=0;i<4;i++) {
   console.log(family[i].name);
}

オブジェクトを関数に渡す

オブジェクトを関数の引数にもできます。 オブジェクトを受取った関数は、そのオブジェクトの プロパティやメソッドを使用できます。

関数 ageDifference はオブジェクトを受取ることで そのプロパティ age を使用し年齢差を計算します。 文字列である名前を受け渡しても計算はできません。

// Person constructor
function Person (name, age) {
    this.name = name;
    this.age = age;
}

// Personオブジェクトを引数にとる関数を作ります。
// この関数は2人の齢の差を計算します。
var ageDifference = function(person1, person2) {
    return person1.age - person2.age;
};

var alice = new Person("Alice", 30);
var billy = new Person("Billy", 25);

// alice と billy の年齢差を関数を使って取得します。
var diff = ageDifference(alice,billy);