// 「prototypeを用いた記述」と「オブジェクトメンバーとしての記述」は挙動が異なります. var foo1 = {method: function method() {;}, member: 10}; var foo2 = {method: function method() {;}, member: 10}; // とすると、methodという名前の関数オブジェクト/10という数値が2箇所で保持されてしまい、非効率です. console.info('foo1.method === foo2.method: ', foo1.method === foo2.method); // これが var Bar = function() {;}; Bar.prototype.method = function method() {;}; Bar.prototype.member = 10; var bar1 = new Bar(); var bar2 = new Bar(); // とすると、methodという名前の関数オブジェクト/10という数値は1箇所で保持されているため、経済的です. console.info('bar1.method === bar2.method: ', bar1.method === bar2.method); // また、名前解決の様子も異なります // // a.bから値を取得するとき、 // 1. aの直接のプロパティにbがあるとき、それを採用 // 2. aの[[Prototype]]のプロパティにbがあるとき、それを採用 // 3. aの[[Prototype]]の[[prototype]]のプロパティにbがあるとき、それを採用 // ... // のように探索されます. // [[Prototype]]は空振りしたときに使われます. // // a.bへの代入は // 1. aの直接のプロパティにbに代入 // です. // 空振りはありえません. console.info('----------------'); console.info('default: foo'); console.info('foo1.member: ', foo1.member); // 10 console.info('foo2.member: ', foo2.member); // 10 console.info('assign: foo1.member = 20;'); foo1.member = 20; console.info('foo1.member: ', foo1.member); // 20 console.info('foo2.member: ', foo2.member); // 10 console.info('delete: delete foo1.member;'); delete foo1.member; console.info('foo1.member: ', foo1.member); // undefined console.info('foo2.member: ', foo2.member); // 10 console.info('----------------'); console.info('default: bar'); console.info('bar1.member: ', bar1.member); // 10 console.info('bar2.member: ', bar2.member); // 10 console.info('assign: Bar.prototype.member = 20;'); Bar.prototype.member = 20; console.info('bar1.member: ', bar1.member); // 20 console.info('bar2.member: ', bar2.member); // 20 console.info('assign: bar1.member = 30;'); bar1.member = 30; console.info('bar1.member: ', bar1.member); // 30 console.info('bar2.member: ', bar2.member); // 20 console.info('delete: delete bar1.member;'); delete bar1.member; console.info('bar1.member: ', bar1.member); // 20 console.info('bar2.member: ', bar2.member); // 20