2011-06-17 37 views
0

我有两个几乎完全相同的以js编写的类。我想让其中一个扩展另一个,以减少代码。我是JavaScript的新手,我需要一点帮助才能做到这一点。 我在这里发布课程。任何人都可以帮忙吗?在javascript中扩展一个类

//============================================================================================================================================ 
     //Class1================================================================================================================================== 
     //============================================================================================================================================ 
     function Class1(config){ 
      var targetObj; 
      var copycanvas = null; 
      var copy = null; 
      var outputcanvas = null; 
      var draw = null; 
      var direction = config.direction || "lr"; 

      var TILE_WIDTH = config.tileWidth || 100; 
      var TILE_HEIGHT = config.tileHeight || 100; 

      var SOURCERECT = {x:0, y:0, width:0, height:0}; 
      var interval; 
      var tiles2 = []; 
      var cols = 0; 
      var rows = 0; 

      createTiles = function(){ 
       tiles = [];  
       tiles2 = [];   

       var y=0; 
       while(y < SOURCERECT.height){ 
        var x=0; 
        cols = 0; 
        while(x < SOURCERECT.width){        
         cols++; 
         x += TILE_WIDTH; 
        } 
        rows++; 
        y += TILE_HEIGHT; 
       } 

       var i, j; 
       if (direction == "tl"){ 
        for (i = 0; i < rows; i++) 
         for (j = 0; j < cols; j++){ 
          x = j * TILE_WIDTH; 
          y = i * TILE_HEIGHT; 
          var tile = new Tile(); 
          tile.imageX = x; 
          tile.imageY = y; 
          tiles2.push(tile); 
         } 
       } 
       arrangeSquares(); 
      }; 

      arrangeSquares = function(){ 
       var i, j, k; 
       var M, N; 

       M = rows; 
       N = cols; 
       i = j = 0; 
       var cnt = 0; 
       for (i = 0; i < N + M - 1; i++) 
        for (j = 0; j <= i; j++) 
         if (j < M && (i - j) < N){ 
          tiles.push(tiles2[j * N + (i - j)]); 
         } 
      } 

      processFrame = function(){ 
       copycanvas.width = outputcanvas.width = targetObj.width; 
       copycanvas.height = outputcanvas.height = targetObj.height; 
       copy.drawImage(targetObj, 0, 0, targetObj.width, targetObj.height); 

       for(var i=0; i < tiles.length; i++) { 
        var tile = tiles[i]; 

        tile.alpha += 0.05; 

        var TH = Math.max(0, Math.min(TILE_HEIGHT, targetObj.height - tile.imageY)); 
        var TW = Math.max(0, Math.min(TILE_WIDTH, targetObj.width - tile.imageX));     

        draw.save(); 
        draw.translate(tile.imageX, tile.imageY); 
        draw.globalAlpha = Math.max(0, tile.alpha);   

        draw.drawImage(copycanvas, tile.imageX, tile.imageY, TW, TH, 0, 0, TW, TH);   
        draw.restore(); 
       } 

       var ok = true; 
       for (i = 0; i < tiles.length; i++) { 
        if (tiles[i].alpha < 1) { 
         ok = false; 
         break; 
        } 
       } 
       if (ok) 
       { 
        clearInterval(interval); 
        showComplete(); 

       } 
      }; 

      function showComplete() { 
       $target.trigger("showComplete"); 

       $img.show(); 
       $(copycanvas).remove(); 
       $(outputcanvas).remove(); 
       if ($hideTarget) 
        $hideTarget.hide(); 
      }; 

      this.hide = function(target) { 

      }; 
      var $target = null; 
      var $img = null; 
      var $hideTarget = null; 
      this.show = function(target, hideTarget){ 
       $target = $("#" + target).show(); 

       align($target); 

       if (hideTarget != undefined) { 
        $target.before($hideTarget = $("#" + hideTarget).show()); 
        align($hideTarget); 
       } 

       $img = $("#" + target + " > img").filter(":first").hide(); 

       $("<canvas/>").attr("id", "sourcecopy") 
           .css("position", "absolute") 
           .appendTo($target) 
           .hide(); 
       copycanvas = document.getElementById("sourcecopy"); 
       copy = copycanvas.getContext('2d'); 

       $("<canvas/>").attr("id", "output") 
           .css("position", "absolute") 
           .appendTo($target); 
       outputcanvas = document.getElementById("output"); 
       draw = outputcanvas.getContext('2d'); 

       targetObj = document.getElementById($img.attr("id")); 

       clearInterval(interval); 

       SOURCERECT = {x:0, y:0, width: targetObj.width, height: targetObj.height}; 
       createTiles(); 

       for(var i=0; i<tiles.length; i++){ 
        var tile = tiles[i]; 
        tile.alpha = 0 - (i * (2/tiles.length)); 
       } 

       var intervalDelay = (config.duration * 1000)/(40 + rows + cols); 
       interval = setInterval(function() { processFrame(); }, intervalDelay); 
      }; 

      function Tile(){ 
       this.alpha = 1; 
       this.imageX = 0; 
       this.imageY = 0; 
      }; 
     }; 

     //============================================================================================================================================ 
     //Class2=================================================================================================================================== 
     //============================================================================================================================================ 
     function Class2(config){ 
      var targetObj; 
      var copycanvas = null; 
      var copy = null; 
      var outputcanvas = null; 
      var draw = null; 
      var direction = config.direction || "lr"; 

      var TILE_WIDTH = config.barWidth || 50; 
      var TILE_HEIGHT = 100; 

      var SOURCERECT = {x:0, y:0, width:0, height:0}; 
      var interval; 
      var tiles = []; 

      createTiles = function(){ 
       tiles = [];    
       var y=0; 
       while(y < SOURCERECT.height){ 
        var x=0; 
        while(x < SOURCERECT.width){ 
         var tile = new Tile(); 
         tile.imageX = x; 
         tile.imageY = y; 
         tiles.push(tile); 
         x += TILE_WIDTH; 
        } 
        y += TILE_HEIGHT; 
       } 
      }; 

      processFrame = function(){ 
       copycanvas.width = outputcanvas.width = targetObj.width; 
       copycanvas.height = outputcanvas.height = targetObj.height; 
       copy.drawImage(targetObj, 0, 0, targetObj.width, targetObj.height); 

       for(var i=0; i < tiles.length; i++) { 
        var tile = tiles[i]; 

        tile.alpha += 0.05; 

        var TH = Math.max(0, Math.min(TILE_HEIGHT, targetObj.height - tile.imageY)); 
        var TW = Math.max(0, Math.min(TILE_WIDTH, targetObj.width - tile.imageX));     

        draw.save(); 
        draw.translate(tile.imageX, tile.imageY); 
        draw.globalAlpha = Math.max(0, tile.alpha);   
        draw.drawImage(copycanvas, tile.imageX, tile.imageY, TW, TH, 0, 0, TW, TH); 
        draw.restore(); 
       } 

       var ok = true; 
       for (i = 0; i < tiles.length; i++) { 
        if (tiles[i].alpha < 1) { 
         ok = false; 
         break; 
        } 
       } 
       if (ok) 
       { 
        clearInterval(interval); 
        showComplete(); 
       } 

      }; 

      function showComplete() { 
       $target.trigger("showComplete"); 

       $img.show(); 
       $(copycanvas).remove(); 
       $(outputcanvas).remove(); 
       if ($hideTarget) 
        $hideTarget.hide(); 
      }; 

      this.hide = function(target) { 

      }; 
      var $target = null; 
      var $img = null; 
      var $hideTarget = null; 
      this.show = function(target, hideTarget){ 
       $target = $("#" + target).show(); 

       align($target); 

       if (hideTarget != undefined) { 
        $target.before($hideTarget = $("#" + hideTarget).show()); 
        align($hideTarget); 
       } 
       $img = $("#" + target + " > img").filter(":first").hide(); 

       $("<canvas/>").attr("id", "sourcecopy") 
           .css("position", "absolute") 
           .appendTo($target) 
           .hide(); 
       copycanvas = document.getElementById("sourcecopy"); 
       copy = copycanvas.getContext('2d'); 

       $("<canvas/>").attr("id", "output") 
           .css("position", "absolute") 
           .appendTo($target); 
       outputcanvas = document.getElementById("output"); 
       draw = outputcanvas.getContext('2d'); 

       targetObj = document.getElementById($img.attr("id")); 

       clearInterval(interval); 

       if (direction == "tb" || direction == "bt") 
       { 
        TILE_WIDTH = targetObj.width; 
        TILE_HEIGHT = config.barWidth; 
       } 
       else 
       { 
        TILE_WIDTH = config.barWidth; 
        TILE_HEIGHT = targetObj.height;   
       } 

       SOURCERECT = {x:0, y:0, width: targetObj.width, height: targetObj.height}; 
       createTiles(); 

       if (direction == "lr" || direction == "tb") 
       { 
        for(var i=0; i<tiles.length; i++){ 
         var tile = tiles[i]; 
         tile.alpha = 0 - (i * (1/tiles.length)); 
        } 
       } 
       else 
       { 
        for(var i=tiles.length - 1; i >= 0 ; i--){ 
         var tile = tiles[i]; 
         tile.alpha = 0 - ((tiles.length - i - 1) * (2/tiles.length)); 
        } 
       } 

       var intervalDelay = (config.duration * 1000)/(40 + tiles.length); 
       interval = setInterval(function() { processFrame(); }, intervalDelay); 
      }; 

      function Tile(){ 
       this.alpha = 1; 
       this.imageX = 0; 
       this.imageY = 0; 
      }; 
     }; 
+0

方式很多代码 – Ibu 2011-06-17 06:55:09

+0

代码并不重要。我已经完全发布了它,以查看类的结构。 – gabitzish 2011-06-17 07:48:43

回答

1

你有一对夫妇的选择。您可以将通用功能隔离为第三个对象,即Class1Class2共享(聚合),或者实际上可以创建对象的层次结构(继承)。我会在这里谈论继承。

JavaScript没有类,它是一个典型的语言。对象实例由原型对象“支持”。如果你向实例请求一个它没有的属性(并且函数作为属性附加到对象上),那么JavaScript解释器会检查该对象后面的原型,以查看它是否具有该属性(如果不是,则返回原型对象等等)。这是原型继承的工作原理。

JavaScript是一种不寻常的原型语言,直到最近,还没有办法创建一个对象并直接分配其原型;你必须通过构造函数来完成它。如果您使用的是基于类的术语,那么无论如何,您可能会更熟悉构造函数。 :-)

这里有一个基本的继承设置(这不是我怎么会真正做到这一点,更多的是下图):

// Constructs an Vehicle instance 
function Vehicle(owner) { 
    this.owner = owner; 
} 

// Who's this Vehicle's owner? 
Vehicle.prototype.getOwner = function() { 
    return this.owner; 
}; 

// Constructs a Car instance 
function Car(owner) { 
    // Call super's initialization 
    Vehicle.call(this, owner); 

    // Our init 
    this.wheels = 4; 
} 

// Assign the object that will "back" all Car instances, 
// then fix up the `constructor` property on it (otherwise 
// `instanceof` breaks). 
Car.prototype = new Vehicle(); 
Car.prototype.constructor = Car; 

// A function that drives the car 
Car.prototype.drive = function() { 
}; 

现在我们可以使用Car并获得Vehicle特点:

var c = new Car("T.J."); 
alert(c.getOwner()); // "T.J.", retrived via Vehicle.prototype.getOwner 

上面有点尴尬,它遇到了一些棘手的问题。它也有问题,大多数函数是匿名的,我不喜欢匿名函数(函数名称help your tools help you)。如果你还有一个函数的副本(如“超级调用”  —不是一种不常见的层次结构操作),那么调用你的原型的函数版本也很尴尬。出于这个原因,您会看到许多用于构建层次结构的“框架”,通常使用基于类的术语。下面是其中一些人的名单:

  • ProotypeClass功能,通用的JavaScript库
  • 院长爱德华兹的base2
  • 约翰Resig的Simple JavaScript Inheritance(Resig的是谁的人创造的jQuery)
  • 呃,恩,mine   —据我所知,约三人正在使用。我这样做是因为我在做出上述每个决定时都有问题。我将更新它以不使用类术语(并且实际上将它作为一个小型库,而不仅仅是一篇博客文章发布),因为它们中没有一个向JavaScript添加类,并且表现得好像错过了JavaScript原型模型的观点。

在这四个中,我推荐Resig's或我的。 Resig使用函数反编译功能(在函数实例上调用toString  ,它从未标准化,在某些平台上不起作用),但即使函数反编译不起作用,它也可以工作,在这种情况下效率稍低。然而,在跳过任何一个之前,我鼓励你看看道格拉斯克罗克福德(Douglas Crockford)所倡导的true prototypical approach(JSON的名声,也是YUI的一个大假发)。克罗克福德在latest version of ECMAScript上投入了大量的意见,他的一些想法(最明显的是Object.create)现在已经成为最新标准的一部分,并正在进入浏览器。使用Object.create,您可以直接将原型分配给对象,而不具有构造函数。

对于需要继承的地方,我更喜欢构造函数(用我的语法帮助),但是克罗克福德的方法是有效的,有用的,并且越来越受欢迎。这是你应该了解和理解的东西,然后选择何时或是否使用。

2

尝试声明这样的类。

var theClass = function theClass() { 
    .... 

扩展这个类可以使用原型法:

theClass.prototype.newMethodName = function() { 
    ....