马赛克板-从构造函数设置变量的最佳实践

时间:2018-11-27 14:22:00

标签: javascript variables constructor

我已经重新格式化了这个问题,以使其更容易理解:

马赛克

我正在创建一个可移动并产生各种动画的马赛克板。

当用户设置电路板时,他们应该将参数传递给构造函数,以便可以将其传递给其他功能。在这里制作了一个新的马赛克,并定义了各种参数,例如颜色,画布的ID和瓷砖大小等。

 var grid = new Mosaic("mosaic_canvas", "#000000", 40, 2, 400, ['#FFFFFF', '#5B95D8', '#E66A87']);

 class Mosaic {

      constructor (canvas_id, bg_colour = "#000000", tile_size, tile_border, tile_qty, colours)

 }

现在,我的问题是如何轻松地在文件中传递所有这些参数? 例如,在镶嵌类中,有一个函数创建网格并调用insertTiles函数。有没有一种简单的方法可以将tile_size,tile_border,canvas高度和宽度传递给这些函数(在类外部)。 诸如画布的高度和宽度之类的东西都使用很多,将它们传递出去的最佳实践是什么?

//Inside of the Mosaic Class
this.createGrid = function() {

    insertTiles();

}

this.createGrid();

//Outside of the Mosaic Class
function insertTiles() {
    var x, y;
    for (let i = 0; i < tile_qty; i++) {
        x = (tile_size + tile_border) * Math.floor(Math.random() * (canvas_width / tile_size)),
        y = (tile_size + tile_border) * Math.floor(Math.random() * (canvas_height / tile_size)),
        console.log("fff");
        tiles.push(newTile(x, y, colours));
    }
}

2 个答案:

答案 0 :(得分:0)

  

我希望这是有道理的

嗯,不是真的,所有这些都不是任何人都应该实际做的,而且看来您认为过程已经进行了“也许我可以使用X来解决问题Y,但是我不知道该怎么做Y的上下文,所以我将向SO询问X的问题,但很少或不提及Y”。

您真的需要Z。

这不一定是答案,因为尚不清楚您的实际问题是什么,但是评论太久了。

要以最简单的方式回答您的问题,只需创建命名变量并将其传递给构造函数即可:

it('should return a 200', async () => {
  const bankOwnerParam = 'someuser@domain.com';
  const bankStub = sinon.stub();

  collectionStub.withArgs(config.get('firestore.bank_collection_key')).returns({ doc: bankStub });
  bankStub.withArgs(bankOwnerParam).returns({ get: () => Promise.resolve({ mykey: 'mydata', exists: true })});

  const req = {"responseId":"RESPONSEID","queryResult":{"queryText":"GOOGLE_ASSISTANT_WELCOME","action":"input.welcome","parameters":{},"allRequiredParamsPresent":true,"fulfillmentMessages":[{"text":{"text":[""]}}],"outputContexts":[{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_welcome"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_audio_output"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/google_assistant_input_type_voice"},{"name":"projects/familybank/agent/sessions/SESSIONID/contexts/actions_capability_media_response_audio"}],"intent":{"name":"projects/familybank/agent/intents/65b6c584-be5d-456b-ad77-341abdb4dcb4","displayName":"Default Welcome Intent"},"intentDetectionConfidence":1.0,"languageCode":"en-us"},"originalDetectIntentRequest":{"source":"google","version":"2","payload":{"isInSandbox":true,"surface":{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.MEDIA_RESPONSE_AUDIO"}]},"requestType":"SIMULATOR","inputs":[{"rawInputs":[{"query":"Talk to Family Bank","inputType":"VOICE"}],"intent":"actions.intent.MAIN"}],"user":{"lastSeen":"2018-11-15T14:41:36Z","accessToken":"TOKEN","locale":"en-US","userId":"USERID"},"conversation":{"conversationId":"SESSIONID","type":"NEW"},"availableSurfaces":[{"capabilities":[{"name":"actions.capability.AUDIO_OUTPUT"},{"name":"actions.capability.SCREEN_OUTPUT"},{"name":"actions.capability.WEB_BROWSER"}]}]}},"session":"projects/familybank/agent/sessions/SESSIONID"};
  const res = {
    response: (code) => {
      assert.equal(code, 200);
    }
  };

  await myFunctions.accessAccount(req, res);
});

但是请注意,由于尚不完全清楚为什么根本需要一个类,或者为什么值如果具有全局可见性,则需要将其作为该特定类的参数,或者为什么不只是公开地指定它们正在构造的实例的可访问属性。

您实际上想在这里完成什么?

答案 1 :(得分:0)

现在就回答您的实际问题:

这不是面向对象软件的工作方式。

如果您要使用面向对象的方法(对于这种用例来说应该是合理的),则该数据属于。似乎您希望能够在同一模块的其他函数中使用传递给对象构造函数的数据。这些函数应该是Mosaic类的方法,否则您应该使用完全不同的方法。

对于具有过多参数的辅助问题,在动态语言(例如JavaScript)中,通常的做法是简单地传递键/值数据结构(例如JavaScript对象):

class Mosaic {
    // here we'll use ES 6 destructuring to pull out the properties we
    // care about from the passed-in object
    constructor ({
        canvas_id, 
        bg_colour = "#000000", // default arguments still work
        tile_size, 
        tile_border, 
        tile_qty, 
        colours
    }) {
        this.tiles = []; // tiles should be a property
        this._canvas = document.getElementById(canvas_id);
        this._tile_size = tile_size;
        // etc etc
    }
}

// note that now we're passing in an object with named properties,
// don't need to remember which is where (less error-prone).
var grid = new Mosaic({canvas_id: "mosaic_canvas", tile_size: 40, /* etc */});

对于您的insertTiles函数,只需使其成为该类的方法即可:

// in class Mosaic definition
insertTiles () {
    var x, y;
    for (let i = 0; i < this.tile_qty; i++) {
        x = (this._tile_size + this._tile_border) * Math.floor(Math.random() * (this._canvas_width / this._tile_size)),
        y = (this._tile_size + this._tile_border) * Math.floor(Math.random() * (this._canvas_height / this._tile_size)),
        console.log("fff");
        this.tiles.push(newTile(x, y, this._colours));
    }
}

您可以对此进行一些调整(例如,平铺不一定是“公共”的),但是总的来说,这就是我们在JS-land上所做的事情。