Aiden
Aiden

Reputation: 1247

Communication between anonymous functions in JavaScript

I could have collected all my code in one single file and put everything in an anonymous function but I was wondering if it was possible to separate them into separate files and let them communicate with each other. Here is an example. Since everything is in anonymous functions I have to use the window object to "get it out" so that the robot.html can access those objects. The problem occurs when the first file tries to access the second file via the method:

Maze.prototype.setWall = function (x, y, direciton) {
    this.spaces[x][y].setWall(direciton);
};

How should I solve this problem?

file 1: maze.js

(function (window) {
    'use strict';

    function Maze (width, height) {
        this.width = width;
        this.height = height;

        this.startX             = null;
        this.startY             = null;
        this.startOrientation   = null;
        this.endX               = null;
        this.endY               = null;

        this.spaces = [];

        var x, y;
        for (x = 1; x <= width; x += 1) {
            this.spaces[x] = [];
            for (y = 1; y <= height; y += 1) {
                this.spaces[x][y] = new MazeSpace();
            }
        }
    }

    Maze.prototype.setStart = function (x, y, orientation) {
        this.startX = x;
        this.startY = y;
        this.startOrientation = orientation;
    };

    Maze.prototype.setEnd = function (x, y) {
        this.endX = x;
        this.endY = y;
    };

    Maze.prototypes.setWall = function (x, y, direciton) {
        this.spaces[x][y].setWall(direciton);
    };

    window.Maze = Maze;

})(window);

file 2: mazespace.js

(function (window) {
    'use strict';

    function MazeSpace () {
        this.north = false;
        this.east = false;
        this.south = false;
        this.west = false;
    }

    MazeSpace.prototype.setWall = function (direction) {
        this[direction] = true;
    };

    window.MazeSpace = MazeSpace;

})(window);

file 3: robot.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>oojs</title>

    <script type="text/javascript" src="maze.js"></script>
    <script type="text/javascript" src="mazespace.js"></script>

    <script>
        var m = new Maze(7, 5);
        m.setStart(1, 1, 'north');
        m.setEnd(7, 1);
        m.setWall(1, 1, 'east');
    </script>

</head>
<body>
</body>
</html>

The console outputs these errors:

Uncaught TypeError: Cannot set property 'setWall' of undefined maze.js:36 Uncaught ReferenceError: Maze is not defined

EDIT:

The errors occurred because of typos.

Upvotes: 1

Views: 840

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1075587

There are two usual answers to this:

  1. Use a single global variable which is an object, and make your "modules" objects referenced by properties on that object (or make your functions properties on that object)

  2. Use an AMD library like RequireJS (this also involves a global — the RequireJS lib itself — but can be useful if your dependencies are at all complex)

For instance, #1 might look something like this:

mazespace.js:

var Amazing = Amazing || {};
Amazing.MazeSpace = (function() {
    // ...

    return MazeSpace;
})();

maze.js:

var Amazing = Amazing || {};
Amazing.Maze = (function() {
    // ...

    return Maze;
})();

Then use Amazing.MazeSpace and Amazing.Maze.

Upvotes: 2

hexerei software
hexerei software

Reputation: 3160

Maybe a simpler solution could be fixing the typo in maze.js. instead of:

Maze.prototypes.setWall = function (x, y, direciton) {
    this.spaces[x][y].setWall(direciton);
};

it should read:

Maze.prototype.setWall = function (x, y, direction) {
    this.spaces[x][y].setWall(direction);
};

you had an extra s at the end of prototype so the function is unknown at later calls (i also fixed spelling error on direction :)

Upvotes: 1

Related Questions