[ Javascript ] 敲開果殼, Override Object Constructor ?

from: freepik.com
Objects, Classes, Prototype, Override, Constructor, Inheritance etc. 這些題目都是 Javascript 新手開發者的痛。由於 Javascript 鬆散結架 (loose comparison) 和自動資料形態轉換 ( type conversion) 特性,在處理 Object 問題上需要更小心。
Default 的 Rabbit Object , 給定 Constructor 使 jumps 的初始值為 yes (stackoverflow)
function Rabbit() {
this.jumps = "yes";
};
var rabbit = new Rabbit();
console.log(rabbit.jumps); // yes
console.log(Rabbit.prototype.constructor); // outputs exactly the code of the function Rabbit();
修改後的 Rabbit Object , 設定新的 Constructor 使 jumps 的初始值為 no。而且 console.log 出現的 constructor 值的確是新設定的 function,但實際執行的結果是舊的 constructor function.
Rabbit.prototype.constructor = function Rabbit() {
this.jumps = "no";
};
console.log(Rabbit.prototype.constructor); // again outputs the code of function Rabbit() and with new this.jumps = "no";
var rabbit2 = new Rabbit(); // create new object with new constructor
console.log(rabbit2.jumps); //
yes
實驗給果,在 Terminal 的 Console.log 都告訴我 Object 的 constructor 已經被更新,但執行結果卻是沒有被更新,為什麼 Javascript 說一套做一套 lol ?
問題在於,object.prototype.constructor 是一個 function pointer, 在 Object 建立 Instance 時執行Pointer 指向的 Function,所以在第一次定義 Constructor 時 Pointer 關系就已經被建立好。第一次定義新 Constructor 時只是把 Object 的Pointer更新,并沒有更新 Instance 原來指向的 Function。
在必要 Overwrite Object Constructor 時,必需重新 Generate 一個 Contructor Function.
var oldProto = Rabbit.prototype;
Rabbit = function() {
this.jumps = "no";
};
Rabbit.prototype = oldProto;

Reference:

Why is it impossible to change constructor function from prototype?
http://js-bits.blogspot.tw/2010/08/javascript-inheritance-done-right.html

Tuesday, August 17, 2010 Javascript Inheritance Done Right
http://stackoverflow.com/questions/9267157/why-is-it-impossible-to-change-constructor-function-from-prototype