prototype(原型) 是 JavaScript 中類的繼承手段;
一個類也不過是一組屬性和方法的集合, 所謂繼承就是繼承屬性或方法;
屬性是個值, 方法是個函數, JavaScript 喜歡把它們都叫成屬性, 我們喜歡把它們叫做成員;
JavaScript 預設讓每個函數都擁有一個 prototype 對象, 它可以指向一個對象或函數(函數也是對象, 一回事);
繞來繞去, 最終是四通八達...
類成員與對象成員
function Rect(w, h) { Rect.name = "My Rect"; //靜態成員屬於類, 不會被對象繼承; 須冠類名調用 this.width = w; //this 是指執行個體化以後的對象或調用該函數的對象 this.height = h; xyz = 123; //這隻能當個內部變數來使用}var r = new Rect();//判斷指定的成員名是否屬於對象alert("width" in r); //truealert("height" in r); //truealert("name" in r); //false//遍曆對象成員for (x in r) { alert(x); //width / height}//遍曆類成員for (x in Rect) { alert(x); //name}
繼承
function Point(x, y) { this.x = x; this.y = y;};function Rect(w, h) { Rect.name = "My Rect"; this.width = w; this.height = h;}Rect.prototype = new Point(); //讓 Rect 再從 Point 類繼承var r = new Rect();//繼承以後就可以這樣使用r.x = 1;r.y = 2;r.width = 3;r.heigth = 4;//遍曆對象成員for (x in r) { alert(x); //y / x / width / height}//遍曆類成員for (x in Rect) { alert(x); //name}//建立方法 constructor 屬於 prototype, 既然 Rect 是繼承與 Point, 那麼:alert(r.constructor); /* 將顯示:function Point(x, y) { this.x = x; this.y = y;};*/
hasOwnProperty、propertyIsEnumerable、isPrototypeOf
function Point(x, y) { this.x = x; this.y = y;};function Rect(w, h) { Rect.name = "My Rect"; this.width = w; this.height = h;}Rect.prototype = new Point();var r = new Rect();/* 可用 hasOwnProperty 方法判斷指定成員是否是對象的固有成員(而非繼承來的) */alert(r.hasOwnProperty('x')); //falsealert(r.hasOwnProperty('y')); //falsealert(r.hasOwnProperty('width')); //truealert(r.hasOwnProperty('height')); //true/* 但不能用 hasOwnProperty 判斷成員是否是繼承來的, 譬如 */alert(r.hasOwnProperty('ABCDEFG')); //false/* propertyIsEnumerable */alert(r.propertyIsEnumerable('x')); //falsealert(r.propertyIsEnumerable('y')); //falsealert(r.propertyIsEnumerable('width')); //truealert(r.propertyIsEnumerable('height')); //true/* isPrototypeOf: 是不是參數(參數是個對象)的原型對象 */alert(Point.prototype.isPrototypeOf(r)); //truealert(Rect.prototype.isPrototypeOf(r)); //truealert(r.isPrototypeOf(r)); //truevar obj = {};alert(Object.prototype.isPrototypeOf(obj)); //truevar str = new String();alert(String.prototype.isPrototypeOf(str)); //truealert(Object.prototype.isPrototypeOf(str)); //true