Javascript 分离通用代码的最佳设计实践?

Javascript 分离通用代码的最佳设计实践?,javascript,oop,Javascript,Oop,我有一门卡片课: function Card() { this.image = new Image(); this.x = 0; this.y = 400; this.initialX = 0; this.initialY = 0; this.scaleFactor = 4; this.setImage = function(ii){ this.image.src = ii;

我有一门卡片课:

function Card()  {
    this.image = new Image();
    this.x = 0;
    this.y = 400;

    this.initialX = 0;
    this.initialY = 0;

    this.scaleFactor = 4;

    this.setImage = function(ii){            
        this.image.src = ii;            
    };

    this.getWidth = function(){        
        if (this.image == null){
            return 0;
        }            
        return this.image.width / this.scaleFactor;        
    }

    this.getHeight = function(){                
        if (this.image == null){
            return 0;
        }            
        return this.image.height / this.scaleFactor;        
    }        

    this.pointIsInCard = function(mx, my){            
        if (mx >= this.x && mx <= (this.x + this.getWidth()) && my >= this.y && my <= (this.y + this.getHeight()))
        {                
            return true;                        
        }
        else{                
            return false;
        }            
    };        
};    

我需要在
Deck
类中添加一个类似于
pointIsInCard
的方法,它将被称为
pointIsInDeck
。逻辑相同,即检查传入点是否落在对象边界内。看到这种代码重复,我想知道什么是避免这种重复的好设计实践?我想到的一个选项是提取出方法,并为通用对象创建一个函数,其中包含
x
y
宽度
高度
,但根据OOP原则,我认为该方法应该属于类/对象。谢谢你的帮助!谢谢

如果这些是与绘图相关的类,它们都将从类似于
矩形的东西继承,它们都将从中继承此行为


如果它们与游戏性相关,我希望它们各自引用一个
矩形
(或其子类),它们将委托所有与UI相关的任务;然后将其简化为上一段的解决方案。

如果这些是与绘图相关的类,它们都将继承类似于
矩形的内容,它们都将继承该行为


如果它们与游戏性相关,我希望它们各自引用一个
矩形
(或其子类),它们将委托所有与UI相关的任务;然后将其简化为上一段的解决方案。

通常的做法是将一个具有该功能的
矩形或类似实例附加到两个对象上,即:

class Rectangle {
    constructor(x, y, width, height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    containsPoint(x, y) {
        return x >= this.x && x =< this.width &&
            y >= this.y && y =< this.height;
    }
}
你可以做到:

card.rect.containsPoint();
deck.rect.containsPoint();

一种常见的方法是将具有该功能的
矩形
或类似实例附加到两个对象上,即:

class Rectangle {
    constructor(x, y, width, height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    containsPoint(x, y) {
        return x >= this.x && x =< this.width &&
            y >= this.y && y =< this.height;
    }
}
你可以做到:

card.rect.containsPoint();
deck.rect.containsPoint();

您可以使用
Function.prototype.call()
在函数调用时设置

function Card()  {
  this.x = 1; this.y = 2;
};

function Deck() {
  this.x = 10; this.y = 20;
}

function points(x, y) {
  // do stuff
  console.log(x, this.x, y, this.y); // `this`: `c` or `d`
}

var c = new Card();

var d = new Deck();

points.call(c, 3, 4); // `this`: `c` within `points` call

points.call(d, 100, 200); // `this`: `d` within `points` call

您可以使用
Function.prototype.call()
在函数调用时设置

function Card()  {
  this.x = 1; this.y = 2;
};

function Deck() {
  this.x = 10; this.y = 20;
}

function points(x, y) {
  // do stuff
  console.log(x, this.x, y, this.y); // `this`: `c` or `d`
}

var c = new Card();

var d = new Deck();

points.call(c, 3, 4); // `this`: `c` within `points` call

points.call(d, 100, 200); // `this`: `d` within `points` call


具有传递要搜索的对象的帮助器类,点坐标,w和h。每个函数的参数相同吗?或者具有具有方法的卡组和卡的超级/祖先。@guest271314是的,函数相同唯一的区别是名称。具有传递要搜索的对象的帮助器类,点坐标,w和h。每个函数的参数都相同吗?或者有一个超级/祖先,即具有该方法的卡组和卡。@guest271314是的,函数相同,唯一的区别是名称。好的,我喜欢这种方法。我喜欢构图而不是继承。我想我会采用这种方法。也许我可以把它命名为boundary,而不是this.rect,在我看来它更具描述性。你觉得怎么样?@user734861仔细想想,我相信bounds实际上是一个更普通的名字:-)谢谢你的建议。我意识到在上面提供的示例中,您使用了类构造,但我认为这是在2015年晚些时候添加的。我使用基于函数的对象创建方法。关于使用类而不是函数,你有什么建议。我唯一担心的是,由于它是一款纸牌游戏,使用旧方法的好处可能是旧浏览器可以使用它。更新版本不能在所有浏览器中都可用。请给出一些建议。@user734861我的建议是在未来项目的工作流程中实现Babel,以充分利用这两个方面(更新的功能和浏览器支持)。好的,我喜欢这种方法。我喜欢构图而不是继承。我想我会采用这种方法。也许我可以把它命名为boundary,而不是this.rect,在我看来它更具描述性。你觉得怎么样?@user734861仔细想想,我相信bounds实际上是一个更普通的名字:-)谢谢你的建议。我意识到在上面提供的示例中,您使用了类构造,但我认为这是在2015年晚些时候添加的。我使用基于函数的对象创建方法。关于使用类而不是函数,你有什么建议。我唯一担心的是,由于它是一款纸牌游戏,使用旧方法的好处可能是旧浏览器可以使用它。更新版本不能在所有浏览器中都可用。请给出一些建议。@user734861我的建议是在您的工作流中实现Babel,以便将来的项目充分利用这两个方面(更新的功能和浏览器支持)。