Javascript模块之间共享的全局变量 [英] Global variables shared amongst Javascript Modules

查看:141
本文介绍了Javascript模块之间共享的全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,我想分开到多个模块。
例如,将我的所有鼠标事件放在另一个模块中(mouseup,mousedown等)。

I have a script that I'd like to seperate out to multiple modules. For example, putting all my mouse events in another module (mouseup, mousedown, etc).

我使用一堆全局变量来跟踪所有我的对象在屏幕上。鼠标模块需要访问这些变量并更改它们。我意识到我可以揭示其他模块所需的每个变量,但它们无法改变它们。

I use a bunch of global variables to keep track of all of my objects on the screen. The mouse module will need to access these variables and alter them. I realize I can reveal each variable needed to other modules, but they are unable to alter them.

如何使用Javascript实现最佳效果?我目前使用揭示模块模式,并且我读到我必须使用getter和setter(例如我从学校回忆的C ++中使用的),但是我有很多全局变量需要跟踪。我需要这些方法中的一些。这是我应该这样做的方式吗?

How is this best achieved using Javascript? I current use the revealing module pattern, and I read that I have to use getters and setters (such as used in C++ from what I recall from school), but I have quite a few global variables to keep track of. I'd need quite a few of these methods. Is this the way I should go about doing so?

或者......这是一个案例,告诉我一个问题描述了糟糕的设计。

Or... is this a case that shows me that an issue describes bad design.

我正在使用Fabric.js进行绘图和所有这些。

I'm using Fabric.js to do the drawing and all that stuff.

drawingcript.js

var DrawScript = function(){

    var DRAW = 0,
        SELECT = 1,
        SCROLL = 2;

    var MOUSEBUTTONS = {
        'S': 83,
        'C': 67,
        'D': 68,
        'DELETE': 46,
        'BACKSPACE': 8
    };

    var canvas;
    var _started       = false;
    var _x, _y;
    var square;
    var edgedetection  = 10; // pixels to snap
    var lines          = {};
    var lines_group;
    var rectangles_group;
    var rectangle_txt  = {};
    var _text_offset_x = 20;
    var _text_offset_y = 20;
    var pressedKeys    = [];

    var _stroke_colour_var    = "red";
    var _stroke_width_var     = 5;
    var _selectionColor       = "rgba(255,255,255,0.4)";
    var _selectionBorderColor = "rgba(0,0,0,0.5)";

    var selectedObjStartSettings = {};
    var resetOpacityOfObject     = false;
    var drawingMode              = true;
    var mouseGlobal              = null;
    var garbage                  = null;

    var window_height        = 0;
    var window_width         = 0;
    var canvasHeight         = 0;
    var canvasWidth          = 0;
    var bg_height            = 0;
    var _canvas_position = {
        'x': {},
        'y': {}
    };
    var _canvas_mouse_pos_x = 0;
    var _canvas_mouse_pos_y = 0;

    var _fullSizeOn      = false;
    var _fullWidth       = 0;
    var _fullHeight      = 0;
    var _fitWidth        = 0;
    var _fitHeight       = 0;
    var _scaleSizeWidth  = 0;
    var _scaleSizeHeight = 0;

    var setCanvasSize = function(){
        // stuff
    },

    checkDrawingMode = function(){
        // stuff
    },

    checkKeyDown = function(e){
        // stuff
    },

    saveDrawing = function(){
        // stuff
    },

    deleteObjectFromCanvas = function (obj){
        // stuff
    },

    setObjectStartPoints = function(){
        // stuff
    },

    drawNewRect = function(top, left, width, height, name){
        // stuff
    },

    updateCoords = function(x, y){
        // stuff
    },

    changeZoom = function(input){
        // stuff
    },

    init = function(){

        garbage = $("#garbage");

        // ===================================
        //  Set drawing mode when changed
        // ===================================
        $("input[name='draw']").change(function(){
            checkDrawingMode();
        });

        // ===================================
        //  Zoom On
        // ===================================
        $("input[name='zoom-on']").change(function(){
            changeZoom(this);
        });

        // ===================================
        //  Check keypress
        // ===================================
        $(document).keydown(function(e){
            checkKeyDown(e);
        });

        $(document).keyup(function(e){
            e.preventDefault();

            var key;

            if(e.metaKey)
            {
                // key = 91;
                return;
            }
            else
                key = e.keyCode;
            pressedKeys[key] = false;

            // console.log(pressedKeys);
        });

        // ===================================
        //  Save drawing
        // ===================================
        $("#save").click(function(){
            saveDrawing();
        });

        $(window).resize(function(){
            setCanvasSize();
        });

        // ===================================
        //  Create canvas and check drawing mode when launched
        // ===================================
        canvas = new fabric.Canvas('demoCanvas');
        setCanvasSize();
        checkDrawingMode();
        canvas.selectionLineWidth = 2;
        canvas.selectionDashArray = [4, 4];
        canvas.cornerColor        = "#900";
        canvas.hoverCursor        = 'pointer';
        canvas.moveCursor         = 'pointer';
        canvas.selection          = false;

        // ===================================
        //  Add groups
        // ===================================
        rectangles_group = new fabric.Group();
        lines_group = new fabric.Group();
        canvas.add(lines_group);

        // ===================================
        //  Get mouse events
        // ===================================
        canvas.on('mouse:down', function(options) { mousedown(options); });
        canvas.on('mouse:move', function(options) { mousemove(options); });
        canvas.on('mouse:up', function(options) { mouseup(options); });
        canvas.on('object:scaling', function(e) { e.target.resizeToScale(rectangle_txt, _text_offset_x, _text_offset_y); });
        canvas.on('object:selected', function() { setObjectStartPoints(); });
        canvas.on('object:moving', function(options) { objectMoving(options); });
    };

    return {
        init: init
    };

}();

为了简洁起见,我删除了顶部的函数实现。
另外,我肯定需要在命名约定方面使我的变量名更加统一。这一切都很早,所以我很抱歉,如果这让任何人想要破坏我的膝盖!

I've removed the function implementations at the top for brevity-sake. Also, I definately need to make my variable names more uniform in terms of naming conventions. This is all pretty early-on so I apologize if this makes anyone want to bust my knee-caps!

我不知道如何拆分鼠标事件所以我的drawScript.js文件不会变成3k行。鼠标事件都使用我设置的各种组和坐标变量。此外,我需要在应用程序使用的脚本中共享画布。

I'm not sure how to split up the mouse events so my drawScript.js file doesn't become 3k lines. The mouse events all use the various groups and coordinate variable I've set up. Also, I need to share the canvas amongst the scripts that the app uses.

也许我只是想努力和过度组织,但我想要求帮助无论如何都会帮助我在大型项目中变得更好:)

Maybe I'm just trying to hard and over-organzing, but I figured asking for help would help me become better at larger projects either way :)

推荐答案

不要使用Revealing Module Pattern。许多人从 Addy Osmani的书中学习了揭示模块模式,而没有注意到 Addy的警告

Don't use the Revealing Module Pattern. Many people learn the Revealing Module Pattern from Addy Osmani's book without paying attention to Addy's warning.

正如您所知,当您将关闭的变量显示给其他模块时,它们无法更改。这是揭示模块模式的根本弱点。你可能做过这样的事情

As you've found out, when you reveal your closured variables to other modules, they cannot be changed. That's a fundamental weakness of the Revealing Module Pattern. You probably did something like this

var mouse = (function(){
  var x = 10, y = 20;
  var drawLineTo = function(x1,y1){
     console.log("Drawing line from " + x + "," + y + " to " + x1 + "," + y1);
  };
  return {
     x: x,
     y: y,
     draw: drawLineTo
  }

})

mouse.x = 50
mouse.draw(15,15) // print "Drawing line from 10,20 to 15,15"

并发现更改 mouse.x 不会更改的值关闭时x 。你可以通过定义明确的getter和setter来解决这个问题。

and found that changing mouse.x doesn't change the value of x in the closure. While you can get around this by defining explicit getters and setters like so

var mouse = (function(){
  var x = 10, y = 20;
  var getX = function() {return x};
  var setX = function(val) {x = val};
  var drawLineTo = function(x1,y1){
     console.log("Drawing line from " + x + "," + y + " to " + x1 + "," + y1);
  };
  return {
     getX : getX,
     setX : setX,
     y: y,
     draw: drawLineTo
  }

})

mouse.setX(50);
mouse.draw(15,15) // print "Drawing line from 10,50 to 15,15"

这只是使用Revealing Module Pattern支付的愚蠢价格。更简单的是

That's just a stupid price to pay for using the Revealing Module Pattern. Much simpler is

var mouse = (function(){
  // put your private variables and methods here.
  return {
     x : 10,
     y: 20,
     draw: function(x1,y1){
        console.log("Drawing line from " + this.x + "," + this.y + " to " + x1 + "," + y1)
     }
  }

})

mouse.x = 50;
mouse.draw(15,15) // print "Drawing line from 50,20 to 15,15"

关键是永远不要透露 - 只将你想隐藏的东西放入封口。打算公开的事情应该是这样的。

The key is to never reveal -- only put the things you intend to hide into the closure. Things intended to be public should be created as such.

这篇关于Javascript模块之间共享的全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆