借這篇文章理清一下自己的思路,同時也希望能給和我同樣一知半解的同學理清一下思路。引發思考來自於我犯的一個錯誤,錯誤碼是這樣的:
var o = { ...}var obj = new o();
結果不用說,當然是報錯的。遺憾的是我以前一直以為var o = { }是定義了一個叫做o的類。然後自己理了一下。得出一下結論:
var o = {}; 等價於 var o = new Object(); 但不等價於 var o = function(){};
第一二種形式 o是一個對象,Object類的對象。第三種形式 o是一個function,更重要的是o是一個類。
var o = {};o.oField = "oField";
等價於
var o = {oField : "oField"}
那問題是:對象上怎麼可以直接定義屬性呢?
由於o是Object類的對象,所以o.prototype是undefined 所以不能這樣 o.prototype.oField = ...
另外,在思考過程中,我寫了兩段測試代碼,一併貼上。可以算是個筆記吧。
//定義類 var Engin = function(){}; //執行個體屬性 Engin.prototype.objectField = "objectField"; //類屬性(靜態域) Engin.classField = "classField"; //執行個體方法 Engin.prototype.objectMethod = function(){ document.write("objectMethod is called<br/>"); } //類方法(靜態方法) Engin.classMethod = function(){ document.write("classMethod is called<br/>"); } //調用執行個體方法 new Engin().objectMethod(); //調用類方法 Engin.classMethod(); document.write(new Engin().objectField + "<br/>"); document.write(Engin.classField + "<br/>"); //只能遍曆出類屬性和類方法 //怎麼遍曆出執行個體屬性和執行個體方法呢? document.write("使用for in 遍曆Engin對象===============================<br/>"); for(var o in Engin){ document.write(o+"<br/>"); } document.write("=======================================================<br/>");
//定義父類Parent,並在父類裡定義了一個屬性pField和一個方法pMethod var Parent = function(){ this.pField = "pField"; this.pMethod = function(){ document.write("pMethod is called<br/>"); } }; //定義父類靜態屬性 Parent.staticPField = "staticPField"; //定義父類靜態方法 Parent.staticPMethod = function(){ document.write("staticPMethod is called<br/>"); } //定義子類Child,並在子類裡定義了一個屬性cField和一個方法cMethod var Child = function(){ this.cField = "cField";//執行個體屬性 this.cMethod = function(){//執行個體方法 document.write("cMethod is called<br/>"); } }; //定義子類靜態屬性 Child.staticCField = "staticCField"; //定義子類靜態方法 Child.staticCMethod = function(){ document.write("staticCMethod is called<br/>"); } //指定Child繼承自Parent Child.prototype = new Parent(); //建立子類對象 var childObj = new Child(); document.write(childObj.pField+"<br/>");//子類對象訪問父類執行個體屬性 //document.write(childObj.staticPField+"<br/>");//子類對象不能訪問父類靜態屬性 childObj.pMethod();//子類對象調用父類執行個體方法 //childObj.staticPMethod();//子類對象不能調用父類靜態方法 document.write(childObj.cField+"<br/>");//子類對象訪問自己的執行個體屬性 document.write(Child.staticCField+"<br/>");//必須使用類名訪問自己的靜態屬性 childObj.cMethod();//子類對象調用自己的執行個體方法 Child.staticCMethod();//必須使用類名來調用自己的靜態方法