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

5,808 views

Published on

2012 年 11 月 29 日の Kyoto.js #2 で発表しました。

「一応 JavaScript を使ってプログラムを書けるが、プロトタイプ継承とかそこらへんの細かいことはちゃんとは理解していない」 というぐらいの初心者向けの発表のつもりでした。 でも実際はあまり初心者向けって感じではないですね。

JavaScript のプロトタイプ継承の説明をするために new 演算子とコンストラクタを使うことが多い気がしますが、Object.create 関数を使って説明した方がわかりやすいのではないか、ということでそういう説明をしてみようというのがこの発表を行った動機です。

ブログ記事 : http://vividcode.hatenablog.com/entry/study-meeting/kyotojs-2-es5-obj-intro

0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,808
On SlideShare
0
From Embeds
0
Number of Embeds
773
Actions
Shares
0
Downloads
22
Comments
0
Likes
14
Embeds 0
No embeds

No notes for slide

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

  1. 1. ECMAScript 5 時代のオブジェクト・プロトタイプ継承入門 id:nobuoka (@nobuoka) 2012-11-29 Kyoto.js #2
  2. 2. 自己紹介と概要● id:nobuoka - はてなブックマークチーム● Java, JavaScript, Ruby あたりの言語が好き● 仕事では Perl と JavaScript● 今日は初心者向けの話 – オブジェクト? – プロトタイプ継承?● ECMA-262 5.1th ベース
  3. 3. ECMAScript とは?● JavaScript の言語コア部分に相当する言語● ECMA International による仕様 : ECMA-262● 最新のバージョンは 5.1 – ECMAScript Language Specification (5.1th) – 古い IE では 5.1 の機能が使えなかったりする – プロトタイプ継承などを 5.1 的に説明してみる (本資料中の節番号は ECMA-262 5.1th の節)
  4. 4. JavaScript におけるオブジェクト● 値の一種 : Object 型の値● Object 型の他には String 型とか Number 型とか● JavaScript には C++ や Smalltalk のようなクラスはな い● オブジェクトリテラルによってやコンストラクタによってな ど、様々な方法で生成されるvar obj1 = { name : “Hanako”, age : 18};var obj2 = new Object();
  5. 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. 6. オブジェクトの同値性 (概念上の話)● もっているプロパティの名前が全て同じで、名前に対応す る値も同じ、という 2 つのオブジェクトがあっても、それら のオブジェクトは同じ値ではない● JavaScript ではオブジェクトそのものが値だから (同じオ ブジェクトでなければ同じ値ではない)// 2 つのオブジェクトは同じ値ではない{ p: “y” } !== { p: “y” } 当たり前といえば当たり前。 C から来た人などは戸惑うかも。
  7. 7. オブジェクトの同値性 (概念上の話)● 引数として渡されたオブジェクトに対する操作は、 もとのオブジェクトに影響する (同じ値なので当然)// 引数として渡されたオブジェクトの val プロパティの// 値をインクリメントする関数function incVal(o) { o.val += 1 }var obj = { val: 10 };incVal(obj); // incVal 呼び出し後の obj.val の値は 11『JavaScript 第 5 版』 では 「参照によるデータ操作」 などと説明されている。 実践的にはそれでいいが、仕様を読むにはここで説明したこと (オブジェクトそのものが値) の理解が必要。
  8. 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. 9. Property Attributes (8.6.1 節)● プロパティの属性 – [[Value]] : データプロパティの値 – [[Writable]] : 書き換えできるか – [[Set]], [[Get]] : setter / getter – [[Configurable]] : 変更できるかどうか – [[Enumerable]] : for-in ループで列挙されるかどうか● Object.getOwnPropertyDescriptor (15.2.3.3 節)
  10. 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. 11. いよいよプロトタイプ継承の話● ECMA-262 5.1th には以下の画像がある● よくわからん
  12. 12. プロトタイプ継承● プロパティの探索を、継承先も (さらにその先祖も) 含めて 行う – クラスベースの言語でのクラスの継承でメソッドの探 索を継承先クラスまで含めるのと同じ● Internal property : [[Prototype]] – 継承先のオブジェクト obj1 - prop1 - prop2// 右図の継承構造があるならobj1.prop1 = 100;console.log( obj2.prop1 ); // 100 obj2 - [[Prototype]]obj1.prop1 = 200; - prop3console.log( obj2.prop1 ); // 200
  13. 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. 14. Object.getPrototypeOf メソッド● 指定したオブジェクトのプロトタイプ継承先を取得// 右図の継承構造をつくるvar obj1 = { /* … */ };var obj2 = Object.create(obj1, { obj1 prop3: { value: 300 } - prop1}); - prop2// プロトタイプ取得 obj2Object.getPrototypeOf(obj2) === obj1; - [[Prototype]] // true - prop3 ブラウザの JavaScript 処理系だと大体 __proto__ ってプロパティがある
  15. 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. 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
  17. 17. おわり

×