Nathan Lee
Nathan Lee

Reputation: 11

js: can class import function from other files?

i was writting a greedy snack game ,but i found that the class GreedySnack has too many big functions.so i want put the functions in other files and import them into the class file. but i jst dont know how to do. part of the codes:

class GreedySnake {
  constructor() {
    this.canvas = document.querySelector("#snake");
    this.ctx = this.canvas.getContext("2d");
    this.maxX = 64; // max row
    this.maxY = 40; // max col
    this.itemWidth = 10; // size of the point
    this.direction = "right"; // up down right left direction
    this.speed = 150; // ms speed
    this.isStop = false; //
    this.isOver = false; //
    this.isStart = false; //
    this.score = 0; //
    this.timer = null; // movement timer
    this.j = 1;
    this.canChange = true;
    this.grid = new Array();

    for (let i = 0; i < this.maxX; i++) {
      for (let j = 0; j < this.maxY; j++) {
        this.grid.push([i, j]);
      }
    }

    // this.drawGridLine();
    this.getDirection();
  }
  // create the body
  createSnake() {
    this.snake = [
      [4, 25],
      [3, 25],
      [2, 25],
      [1, 25],
      [0, 25],
    ];
  }

  // movement
  move() {
    ...

    // if the next-step is not food
    ...
  }

  // start
  start() {
    ...
  }
  // pause
  stop() {
    ...
  }
}




i've tired the require

createPos = require("./food");
  createFood = require("./food");
snackClass.js:29 Uncaught ReferenceError: require is not defined

Upvotes: 0

Views: 156

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074138

You can use functions defined elsewhere as functions in your class, although they won't be methods in the ES2015+ sense (specifically: they can't use super). They'll still be "methods" in the general sense that you call them on the instance and they work just like real methods. (They'll be like the methods we used to have before ES2015's class syntax.) You can even set them up using modern property syntax.

Here's a simple example:

// The functions declared elsewhere
function start() {
    console.log(`Doing a start operation for ${this.name}`);
}
function stop() {
    console.log(`Doing a stop operation for ${this.name}`);
}

// The class
class Example {
    constructor(name) {
        this.name = name;
    }

    // Using property syntax to set up the `start` and `stop` "methods"
    start = start;
    stop = stop;
}

// Using it
const e = new Example("test");
e.start();
e.stop();

Unlike true methods, those:

  1. Will be "own" properties of each instance, not prototype properies
  2. Will be enumerable

You could fix #1 by assigning them to your constructor functions' prototype object instead:

// The functions declared elsewhere
function start() {
    console.log(`Doing a start operation for ${this.name}`);
}
function stop() {
    console.log(`Doing a stop operation for ${this.name}`);
}

// The class
class Example {
    constructor(name) {
        this.name = name;
    }
}
Object.assign(Example.prototype, { start, stop });

// Using it
const e = new Example("test");
e.start();
e.stop();

You can fix #2 by using Object.defineProperty (or Object.defineProperties):

// The functions declared elsewhere
function start() {
    console.log(`Doing a start operation for ${this.name}`);
}
function stop() {
    console.log(`Doing a stop operation for ${this.name}`);
}

// The class
class Example {
    constructor(name) {
        this.name = name;
    }
}
for (const [name, method] of Object.entries({start, stop})) {
    Object.defineProperty(Example.prototype, name, {
        value: method,
        writable: true,
        configurable: true,
    })
}

// Using it
const e = new Example("test");
e.start();
e.stop();

Upvotes: 1

Related Questions