ExtJS的物件導向編程(繼承、重寫),extjs物件導向編程
<link rel="stylesheet" type="text/css" href="<%=basePath %>/ext-3.4/resources/css/ext-all.css"> <script type="text/javascript" src="<%=basePath%>/ext-3.4/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="<%=basePath%>/ext-3.4/ext-all.js"></script> <script type="text/javascript"> // ExtJS在支援物件導向編程中比JavaScript更接近傳統的物件導向編程,提供的方法有: // extend、apply/applyif(屬性嵌套)、override、namespaces/ns // 定義交通工具類(父類) function Vehicle(){ this.x = 0; this.y = 0; } Vehicle.prototype.move=function(dx,dy){ this.x += dx; this.y += dy; } // 汽車只在水平方法行駛 function Car(){ Car.prototype = new Vehicle(); Car.prototype.move = function(dx){ this.x += dx; } } // 電梯只在垂直方向行駛 function Elevator(){ Elevator.prototype = new Vehicle(); Elevator.prototype.move = function(dy){ this.y += dy; } } // 使用對象作為設定參數 function Vehicle(config){ this.x = config.x; this.y = config.y; } Vehicle.prototype.toString = function(){ return "Point:("+x+","+y+")"; } function Car(config){ // 明確scope為Car執行個體 Vehicle.prototype.constructor.call(this,config); this.color = config.color; } // 使用Ext提供的extend函數 Ext.extend(Car,Vehicle,{ // 重寫父類move move:function(dx){ this.x += dx; }, // 重寫父類的toString toString:function(){ var str = "Car is"+this.x+" miles away from original position"; str += "this car is "+this.color; return str; } }); var config = {x:10,y:0,color:"white"}; var car = new Car(config); car.move(150); console.info(car.toString()); // Ext.extend保留父類與子類同名的屬性,ExtJS可以直接產生重寫的子類 // 只需要先定義父類,然後定義一個變數,將Ext.extend返回的子類賦給這個變數即可 var Taxi = Ext.extend(Vehicle,{ // 建構函式也可以重寫 constructor:function(){ Vehicle.prototype.constructor.call(this,config); this.color = config.color; }, // 重寫move方法 move:function(dx){ this.x+=dx; }, // 重寫toString方法 toString:function(){ var str = "Taxi is"+this.x+" miles away from original position"; str += "this car is "+this.color; return str; } }); var taxiConfig = {x:10,y:0,color:"white"}; var taxi = new Taxi(taxiConfig); taxi.move(150); console.info(taxi.toString()); // 註: // 在定義子類的時候往往需要重寫一些從父類繼承而來的屬性。編寫視圖組件的時候,特別容易混淆屬性究竟是在父類還是在子類一般是: // 1、如果父類中定義有這個屬性,就使用新的值代替父類中的屬性值 // 2、如果父類沒有定義這個屬性,就不用覆蓋 // 3、在設定父類屬性時,有預設值用於輔助設定 // 以上需求可以使用apply/applyif來滿足,如下: var config1 = {width:100,height:200,alpha:1}; var config2 = {widht:100,height:0.5,alpha:25}; console.debug("before Ext.apply() config1 with [%d,%d] alpha:%f", config1.width, config1.height, config1.alpha ); // 不管Config1原有屬性存在否,一律重寫 // 第一個參數是目的對象,第二個參數是來源物件 // 把config2的屬性拷貝覆蓋config1的屬性 Ext.apply(config1,config2); console.debug("After Ext.apply() config1 with [%d,%d] alpha:%f", config1.width, config1.height, config1.alpha, config1.angle ); // 如果不希望重寫,可以改用applyIf(),父類已經有既定的值,這個值將不會被重寫。但不管apply還是applyIf,config2如果含有config1 // 不存在的屬性,這個屬性會自動複製到config1中,Ext.apply還接收第三個參數,作為預設值使用 // 組件可能的預設值 var defaults = {width:50,alpha:1,color:"white"}; var config3 = {width:100,height:200,alpha:1}; var config4 = {width:150,alpha:2,angle:25}; console.debug("before Ext.apply() config1 with [%d,%d] alpha:%f", config3.width, config3.height, config3.alpha ); Ext.apply(config3,config4,defaults); console.debug("After Ext.apply() config1 with [%d,%d] alpha:%f", config3.width, config3.height, config3.alpha, config3.angle, config3.color ); // Ext.override()方法提供了重寫方法的一種途徑,他有兩個參數,一個是要重寫的類,另一個是要重寫的方法(用對象封裝) function Bus(){ } Bus.prototype.move = function(){ return "Bus move"; } Bus.prototype.toString = function(){ return "this is a bus"; } Ext.override(Bus,{ move:function(){ return "Bus move on road"; }, toString:function(){ return "this is a beautiful bus"; }, nice:"不是方法也可以重寫" }) var bus = new Bus(); console.info(bus.move()); console.info(bus.toString()); console.info(bus.nice); </script>