SlideShare a Scribd company logo
1 of 17
Download to read offline
ECMAScript 5 時代の
オブジェクト・プロトタイプ継承入門



       id:nobuoka
         (@nobuoka)

     2012-11-29 Kyoto.js #2
自己紹介と概要
●   id:nobuoka - はてなブックマークチーム
●   Java, JavaScript, Ruby あたりの言語が好き
●   仕事では Perl と JavaScript

●   今日は初心者向けの話
    –   オブジェクト?
    –   プロトタイプ継承?
●
    ECMA-262 5.1th ベース
ECMAScript とは?
●   JavaScript の言語コア部分に相当する言語
●   ECMA International による仕様 : ECMA-262
●   最新のバージョンは 5.1
    –   ECMAScript Language Specification (5.1th)
    –   古い IE では 5.1 の機能が使えなかったりする
    –   プロトタイプ継承などを 5.1 的に説明してみる
        (本資料中の節番号は
         ECMA-262 5.1th の節)
JavaScript におけるオブジェクト
●   値の一種 : Object 型の値
●   Object 型の他には String 型とか Number 型とか
●   JavaScript には C++ や Smalltalk のようなクラスはな
    い
●   オブジェクトリテラルによってやコンストラクタによってな
    ど、様々な方法で生成される

var obj1 = {
    name : “Hanako”,
    age : 18
};
var obj2 = new Object();
オブジェクトはプロパティの集合体
●   “An Object is a collection of properties.” (8.6 節)
●   プロパティ : 名前と値の結合物 (association)
    –   Named data property : プロパティといえばこれ
    –   Named accessor property
    –   Internal property : 仕様説明のための内部的なもの

           var obj1 = {
               name : “Hanako”,
               age : 18             名前は age, 値は数値
           };                       18 であるプロパティ
オブジェクトの同値性 (概念上の話)
●   もっているプロパティの名前が全て同じで、名前に対応す
    る値も同じ、という 2 つのオブジェクトがあっても、それら
    のオブジェクトは同じ値ではない
●   JavaScript ではオブジェクトそのものが値だから (同じオ
    ブジェクトでなければ同じ値ではない)

// 2 つのオブジェクトは同じ値ではない
{ p: “y” } !== { p: “y” }

                   当たり前といえば当たり前。
                   C から来た人などは戸惑うかも。
オブジェクトの同値性 (概念上の話)
●   引数として渡されたオブジェクトに対する操作は、
    もとのオブジェクトに影響する (同じ値なので当然)
// 引数として渡されたオブジェクトの val プロパティの
// 値をインクリメントする関数
function incVal(o) { o.val += 1 }
var obj = { val: 10 };
incVal(obj); // incVal 呼び出し後の obj.val の値は 11

『JavaScript 第 5 版』 では 「参照によるデータ操作」 など
と説明されている。 実践的にはそれでいいが、仕様を読むに
はここで説明したこと (オブジェクトそのものが値) の理解が必要。
Accessor property
●   いわゆる setter / getter
●   最近のブラウザなら (IE10 含め) 基本的に使える

var obj = {
    _val: 0,
    get val() { return this._val },
    set val(v) { this._val = v }
};
obj.val = obj.val + 10;
Property Attributes (8.6.1 節)
●   プロパティの属性
    – [[Value]] : データプロパティの値
    – [[Writable]] : 書き換えできるか
    – [[Set]], [[Get]] : setter / getter
    – [[Configurable]] : 変更できるかどうか
    – [[Enumerable]] : for-in ループで列挙されるかどうか
●   Object.getOwnPropertyDescriptor (15.2.3.3 節)
Object.defineProperty (15.2.3.6 節)
●   Property Attributes を指定してプロパティを定義
●   Object.defineProperties もあるよ (15.2.3.7 節)
var obj = {};
Object.defineProperty(obj, “newProp”, {
    value: 200,
    writable: false
});
obj.newProp = 10; // writable : false なので書きこまれない

Object.defineProperties(obj, {
    newProp2: {
      get: function () { return 200 }
    }
});         他には __defineGetter__, __defineSetter__ とか
いよいよプロトタイプ継承の話
●
    ECMA-262 5.1th には以下の画像がある
●   よくわからん
プロトタイプ継承
●   プロパティの探索を、継承先も (さらにその先祖も) 含めて
    行う
    –  クラスベースの言語でのクラスの継承でメソッドの探
       索を継承先クラスまで含めるのと同じ
●   Internal property : [[Prototype]]
    –   継承先のオブジェクト                       obj1
                                    - prop1
                                    - prop2
// 右図の継承構造があるなら
obj1.prop1 = 100;
console.log( obj2.prop1 ); // 100         obj2
                                    - [[Prototype]]
obj1.prop1 = 200;                   - prop3
console.log( obj2.prop1 ); // 200
Object.create メソッド
●   指定したオブジェクトを継承した新しいオブジェクトを生
    成

// 右図の継承構造をつくる
var obj1 = {
    prop1: 100,
    prop2: 200                          obj1
                                   - prop1
};                                 - prop2

// obj2 は obj1 を継承
var obj2 = Object.create(obj1, {         obj2
                                   - [[Prototype]]
     prop3: { value: 300 }         - prop3
});
Object.getPrototypeOf メソッド
●   指定したオブジェクトのプロトタイプ継承先を取得

// 右図の継承構造をつくる
var obj1 = { /* … */ };
var obj2 = Object.create(obj1, {
                                             obj1
    prop3: { value: 300 }               - prop1
});                                     - prop2


// プロトタイプ取得
                                              obj2
Object.getPrototypeOf(obj2) === obj1;   - [[Prototype]]
    // true                             - prop3


                   ブラウザの JavaScript 処理系だと大体
                   __proto__ ってプロパティがある
コンストラクタによるオブジェクト生成
●   “constructor : function object that creates and
    initialises objects” (4.3.4 節)
●   new 演算子

function Cons() {
    this.prop = 200;
}
var obj = new Cons();

console.log( obj.prop ); / 200
                          /
コンストラクタの prototype プロパティ
●   “When a constructor creates an object, that object
    implicitly references the constructor’s “prototype”
    property for the purpose of resolving property
    references.” (4.3.5 節)
    –   コンストラクタの prototype プロパティの値が新たな
        オブジェクトの [[Prototype]] に設定される

                            Cons       Cons.prototype
                         - prototype      - prop1
                                          - prop2



                 obj2
           - [[Prototype]]
           - prop3
おわり

More Related Content

More from Yu Nobuoka

AndroidJUnitRunner で JUnit 4 形式のテストに移行
AndroidJUnitRunner で JUnit 4 形式のテストに移行AndroidJUnitRunner で JUnit 4 形式のテストに移行
AndroidJUnitRunner で JUnit 4 形式のテストに移行Yu Nobuoka
 
Android アプリ開発における Gradle ビルドシステム
Android アプリ開発における Gradle ビルドシステムAndroid アプリ開発における Gradle ビルドシステム
Android アプリ開発における Gradle ビルドシステムYu Nobuoka
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Yu Nobuoka
 
はてなにおける Android アプリのソフトウェアテスト
はてなにおける Android アプリのソフトウェアテストはてなにおける Android アプリのソフトウェアテスト
はてなにおける Android アプリのソフトウェアテストYu Nobuoka
 
GIF と LZW 圧縮と GifWriter.js
GIF と LZW 圧縮と GifWriter.jsGIF と LZW 圧縮と GifWriter.js
GIF と LZW 圧縮と GifWriter.jsYu Nobuoka
 
Windows ストアアプリのつくりかた (JS + HTML + CSS)
Windows ストアアプリのつくりかた (JS + HTML + CSS)Windows ストアアプリのつくりかた (JS + HTML + CSS)
Windows ストアアプリのつくりかた (JS + HTML + CSS)Yu Nobuoka
 
GUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCGUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCYu Nobuoka
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめYu Nobuoka
 
WebSocket Protocol と Plack::Middleware::WebSocket
WebSocket Protocol と Plack::Middleware::WebSocketWebSocket Protocol と Plack::Middleware::WebSocket
WebSocket Protocol と Plack::Middleware::WebSocketYu Nobuoka
 

More from Yu Nobuoka (9)

AndroidJUnitRunner で JUnit 4 形式のテストに移行
AndroidJUnitRunner で JUnit 4 形式のテストに移行AndroidJUnitRunner で JUnit 4 形式のテストに移行
AndroidJUnitRunner で JUnit 4 形式のテストに移行
 
Android アプリ開発における Gradle ビルドシステム
Android アプリ開発における Gradle ビルドシステムAndroid アプリ開発における Gradle ビルドシステム
Android アプリ開発における Gradle ビルドシステム
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成
 
はてなにおける Android アプリのソフトウェアテスト
はてなにおける Android アプリのソフトウェアテストはてなにおける Android アプリのソフトウェアテスト
はてなにおける Android アプリのソフトウェアテスト
 
GIF と LZW 圧縮と GifWriter.js
GIF と LZW 圧縮と GifWriter.jsGIF と LZW 圧縮と GifWriter.js
GIF と LZW 圧縮と GifWriter.js
 
Windows ストアアプリのつくりかた (JS + HTML + CSS)
Windows ストアアプリのつくりかた (JS + HTML + CSS)Windows ストアアプリのつくりかた (JS + HTML + CSS)
Windows ストアアプリのつくりかた (JS + HTML + CSS)
 
GUI アプリケーションにおける MVC
GUI アプリケーションにおける MVCGUI アプリケーションにおける MVC
GUI アプリケーションにおける MVC
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
WebSocket Protocol と Plack::Middleware::WebSocket
WebSocket Protocol と Plack::Middleware::WebSocketWebSocket Protocol と Plack::Middleware::WebSocket
WebSocket Protocol と Plack::Middleware::WebSocket
 

ECMAScript 5 時代のオブジェクト・プロトタイプ継承入門

  • 2. 自己紹介と概要 ● id:nobuoka - はてなブックマークチーム ● Java, JavaScript, Ruby あたりの言語が好き ● 仕事では Perl と JavaScript ● 今日は初心者向けの話 – オブジェクト? – プロトタイプ継承? ● ECMA-262 5.1th ベース
  • 3. ECMAScript とは? ● JavaScript の言語コア部分に相当する言語 ● ECMA International による仕様 : ECMA-262 ● 最新のバージョンは 5.1 – ECMAScript Language Specification (5.1th) – 古い IE では 5.1 の機能が使えなかったりする – プロトタイプ継承などを 5.1 的に説明してみる (本資料中の節番号は ECMA-262 5.1th の節)
  • 4. JavaScript におけるオブジェクト ● 値の一種 : Object 型の値 ● Object 型の他には String 型とか Number 型とか ● JavaScript には C++ や Smalltalk のようなクラスはな い ● オブジェクトリテラルによってやコンストラクタによってな ど、様々な方法で生成される var obj1 = { name : “Hanako”, age : 18 }; var obj2 = new Object();
  • 5. オブジェクトはプロパティの集合体 ● “An Object is a collection of properties.” (8.6 節) ● プロパティ : 名前と値の結合物 (association) – Named data property : プロパティといえばこれ – Named accessor property – Internal property : 仕様説明のための内部的なもの var obj1 = { name : “Hanako”, age : 18 名前は age, 値は数値 }; 18 であるプロパティ
  • 6. オブジェクトの同値性 (概念上の話) ● もっているプロパティの名前が全て同じで、名前に対応す る値も同じ、という 2 つのオブジェクトがあっても、それら のオブジェクトは同じ値ではない ● JavaScript ではオブジェクトそのものが値だから (同じオ ブジェクトでなければ同じ値ではない) // 2 つのオブジェクトは同じ値ではない { p: “y” } !== { p: “y” } 当たり前といえば当たり前。 C から来た人などは戸惑うかも。
  • 7. オブジェクトの同値性 (概念上の話) ● 引数として渡されたオブジェクトに対する操作は、 もとのオブジェクトに影響する (同じ値なので当然) // 引数として渡されたオブジェクトの val プロパティの // 値をインクリメントする関数 function incVal(o) { o.val += 1 } var obj = { val: 10 }; incVal(obj); // incVal 呼び出し後の obj.val の値は 11 『JavaScript 第 5 版』 では 「参照によるデータ操作」 など と説明されている。 実践的にはそれでいいが、仕様を読むに はここで説明したこと (オブジェクトそのものが値) の理解が必要。
  • 8. Accessor property ● いわゆる setter / getter ● 最近のブラウザなら (IE10 含め) 基本的に使える var obj = { _val: 0, get val() { return this._val }, set val(v) { this._val = v } }; obj.val = obj.val + 10;
  • 9. Property Attributes (8.6.1 節) ● プロパティの属性 – [[Value]] : データプロパティの値 – [[Writable]] : 書き換えできるか – [[Set]], [[Get]] : setter / getter – [[Configurable]] : 変更できるかどうか – [[Enumerable]] : for-in ループで列挙されるかどうか ● Object.getOwnPropertyDescriptor (15.2.3.3 節)
  • 10. Object.defineProperty (15.2.3.6 節) ● Property Attributes を指定してプロパティを定義 ● Object.defineProperties もあるよ (15.2.3.7 節) var obj = {}; Object.defineProperty(obj, “newProp”, { value: 200, writable: false }); obj.newProp = 10; // writable : false なので書きこまれない Object.defineProperties(obj, { newProp2: { get: function () { return 200 } } }); 他には __defineGetter__, __defineSetter__ とか
  • 11. いよいよプロトタイプ継承の話 ● ECMA-262 5.1th には以下の画像がある ● よくわからん
  • 12. プロトタイプ継承 ● プロパティの探索を、継承先も (さらにその先祖も) 含めて 行う – クラスベースの言語でのクラスの継承でメソッドの探 索を継承先クラスまで含めるのと同じ ● Internal property : [[Prototype]] – 継承先のオブジェクト obj1 - prop1 - prop2 // 右図の継承構造があるなら obj1.prop1 = 100; console.log( obj2.prop1 ); // 100 obj2 - [[Prototype]] obj1.prop1 = 200; - prop3 console.log( obj2.prop1 ); // 200
  • 13. Object.create メソッド ● 指定したオブジェクトを継承した新しいオブジェクトを生 成 // 右図の継承構造をつくる var obj1 = { prop1: 100, prop2: 200 obj1 - prop1 }; - prop2 // obj2 は obj1 を継承 var obj2 = Object.create(obj1, { obj2 - [[Prototype]] prop3: { value: 300 } - prop3 });
  • 14. Object.getPrototypeOf メソッド ● 指定したオブジェクトのプロトタイプ継承先を取得 // 右図の継承構造をつくる var obj1 = { /* … */ }; var obj2 = Object.create(obj1, { obj1 prop3: { value: 300 } - prop1 }); - prop2 // プロトタイプ取得 obj2 Object.getPrototypeOf(obj2) === obj1; - [[Prototype]] // true - prop3 ブラウザの JavaScript 処理系だと大体 __proto__ ってプロパティがある
  • 15. コンストラクタによるオブジェクト生成 ● “constructor : function object that creates and initialises objects” (4.3.4 節) ● new 演算子 function Cons() { this.prop = 200; } var obj = new Cons(); console.log( obj.prop ); / 200 /
  • 16. コンストラクタの prototype プロパティ ● “When a constructor creates an object, that object implicitly references the constructor’s “prototype” property for the purpose of resolving property references.” (4.3.5 節) – コンストラクタの prototype プロパティの値が新たな オブジェクトの [[Prototype]] に設定される Cons Cons.prototype - prototype - prop1 - prop2 obj2 - [[Prototype]] - prop3