VScode 如何在拆分.js 文件时阻止某些函数的内容未定义?

In VScode how can I stop the content of some functions being undefined when splitting .js files?

一旦我将 javascript 文件分成两个单独的文件 VScode intellisense 告诉我与第一个文件相关的所有变量和函数在第二个文件中未定义,但脚本运行在浏览器中正常!

文件logic.js是在main.js中调用的一个大函数。

如果我在一个巨大的函数中没有 logic.js 它可以工作,但它需要在一个函数中。

如果我只是将 logic.js 的内容复制并粘贴到 main.js 的末尾就可以了...我不明白 VScode 中发生了什么。

我调用body中的脚本(我试过head结果一样)

<body onload="mainLoop()">
<canvas id="canvas" width="650" height="650">Sorry, your browser can't display canvas!</canvas>
<script src="logic.js"></script>
<script src="main.js"></script>

我可以以相反的顺序调用文件,同样的事情发生了,程序运行正常,但 VSCode 停止了在 logic.js.

这个巨大函数中工作的智能感知

更新这里有 2 个文件:

// 文件 1 main.js

"use strict";

// Set variables

/** @type {HTMLCanvasElement} */
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

let rightPressed = false;
let leftPressed = false;

var heroRotation = 0;
var bulletFired = false;
var numberOfZombies = 20;


/**
 * @description general purpose renderer
 * @param {*} state - the name of the object to act on
 */

function render2(state) {
    ctx.save();
    ctx.translate(state.xPosition, state.yPosition);
    ctx.rotate(state.angle * Math.PI / 180);
    ctx.fillStyle = state.color;
    ctx.fillRect(state.width / -2, state.height / -2, state.width, state.height);
    ctx.restore();
}


/**
 * @description fire the heros gun
 * @param {*} state 
 */

function fire(state) {
    let fireangle = hero.angle;
    // while (state.xPosition > 50 && state.xPosition < (canvas.width - 50) || state.yPosition > 50 && state.yPosition < (canvas.height - 50)) {
    state.xPosition += 1 * Math.sin(fireangle);
    state.yPosition -= 1 * Math.cos(fireangle);
    // }
}


/**
 * @description Render the zombie objects
 */

function renderZombies() {
    for (let i = 0; i < allmyzombies.length; i++) {
        render2(allmyzombies[i]);
    }
}


/**
 * @description clear the canvas
 */

function clearCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

// Factory functions

const createZombie = ({
    status = 1,
    width = 10,
    height = 10,
    xPosition,
    yPosition,
    angle = 0,
    color = "green"
}) => ({
    status,
    width,
    height,
    xPosition,
    yPosition,
    angle,
    color
});

const createHero = ({
    status = 1,
    width = 25,
    height = 50,
    xPosition,
    yPosition,
    angle = 0,
    color = "red"
}) => ({
    status,
    width,
    height,
    xPosition,
    yPosition,
    angle,
    color
});

const createBullet = ({
    status = 1,
    width = 5,
    height = 10,
    xPosition,
    yPosition,
    angle = 0,
    color = "white"
}) => ({
    status,
    width,
    height,
    xPosition,
    yPosition,
    angle,
    color
});


// Create the zombie objects using the factory function
var allmyzombies = [];

function createZombies(numberOfZombies) {

    for (let i = 0; i < numberOfZombies; i++) {

        let x = Math.floor(Math.random() * canvas.width);

        if (x > (canvas.width / 2)) {
            x += (canvas.width / 3);
        } else {
            x -= (canvas.width / 3);
        }

        let y = Math.floor(Math.random() * canvas.height);

        if (y > (canvas.height / 2)) {
            y += (canvas.width / 3);
        } else {
            y -= (canvas.height / 3);
        }

        allmyzombies[i] = createZombie({
            xPosition: x,
            yPosition: y
        });
    }
}

createZombies(numberOfZombies);

// create the hero using the factory function

const hero = createHero({
    xPosition: canvas.width / 2,
    yPosition: canvas.height / 2
});


// create the bullet using the factory function
// HOW TO USE BULLET WIDTH TO GET IN THE MIDDLE BEFORE ITS MADE?!

const bullet = createBullet({
    xPosition: (canvas.width + hero.width) / 2,
    yPosition: (canvas.height + hero.height) / 2
});


// Add event listener for keyboard handler

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

/**
 * @description keyDownHandler
 * @param {*} event - the event from the eventListener
 */

function keyDownHandler(event) {

    switch (event.code) {
        case "KeyF":
            bulletFired = true;
            break;
        case "ArrowLeft":
            leftPressed = true;
            break;
        case "ArrowRight":
            rightPressed = true;
            break;
    }
    event.preventDefault();
}


/**
 * @description keyUpHandler
 * @param {*} event - the event from the eventListener
 */

function keyUpHandler(event) {
    switch (event.code) {
        case "ArrowLeft":
            leftPressed = false;
            break;
        case "ArrowRight":
            rightPressed = false;
            break;
    }
    event.preventDefault();
}

function mainLoop() {
    clearCanvas();
    renderZombies();
    render2(hero);
    render2(bullet);
    logic();
    requestAnimationFrame(mainLoop); // keeps running draw 60fps on paint
}


mainLoop(); // Call main loop function

// 文件 2 Logic.js

/**
 * @description game logic
 */

function logic() {
    for (let zombie of allmyzombies) {

        function moveZombieUp() {
            zombie.yPosition -= ZombieSpeed;
        }

        function moveZombieDown() {
            zombie.yPosition += ZombieSpeed;
        }

        function moveZombieLeft() {
            zombie.xPosition -= ZombieSpeed;
        }

        function moveZombieRight() {
            zombie.xPosition += ZombieSpeed;
        }

        let zombieStupidity = Math.random();
        let zombieStupidityThreshold = 0.75;

        if (zombieStupidity > zombieStupidityThreshold) {
            var zombieIsStupid = true;
        } else {
            var zombieIsStupid = false;
        }

        let ZombieSpeed = (Math.random() * 0.5);
        let zombieIsRightOfHero = zombie.xPosition > hero.xPosition;
        let zombieIsLeftOfHero = zombie.xPosition < hero.xPosition;
        let zombieIsBelowHero = zombie.yPosition > hero.yPosition;
        let zombieIsAboveHero = zombie.yPosition < hero.yPosition;

        if (zombieIsRightOfHero) {
            if (zombieIsStupid) {
                moveZombieRight();
            } else {
                moveZombieLeft();
            }
        }
        if (zombieIsLeftOfHero) {
            if (zombieIsStupid) {
                moveZombieLeft();
            } else
                moveZombieRight();
        }
        if (zombieIsBelowHero) {
            if (zombieIsStupid) {
                moveZombieDown();
            } else
                moveZombieUp();
        }
        if (zombieIsAboveHero) {
            if (zombieIsStupid) {
                moveZombieUp();
            } else
                moveZombieDown();
        }
        // detect zombie hero collision
        if (zombie.xPosition < hero.xPosition + hero.width &&
            zombie.xPosition + zombie.width > hero.xPosition &&
            zombie.yPosition < hero.yPosition + hero.height &&
            zombie.height + zombie.yPosition > hero.yPosition) {
            throw new Error("You died!");
        }
        // detect zombie bullet collision
        if (zombie.xPosition < bullet.xPosition + bullet.width &&
            zombie.xPosition + zombie.width > bullet.xPosition &&
            zombie.yPosition < bullet.yPosition + bullet.height &&
            zombie.height + zombie.yPosition > bullet.yPosition) {
            throw new Error("You killed a zombie!");
        }
    }

    if (bulletFired) {
        fire(bullet);
    }

    if (bullet.yPosition < 50 || bullet.yPosition > (canvas.height - 50)) {
        bulletFired = false;
    }

    // act on keypress controller info to rotate hero
    if (rightPressed) {
        hero.angle += 1;
    } else if (leftPressed) {
        hero.angle -= 1;
    }
}

与VS代码无关。

第一个加载到html上的文件可以被后面的文件识别 在您的情况下,logic.js 函数和变量可用于 main.js

所以你需要对它们进行正确排序,并确保没有双向依赖关系。比如main.js调用logic.js函数,logic.js调用main.js函数。

您需要按照依赖顺序对html中的js文件进行排序。 如果你post你的代码

,给出一个具体的例子会更容易

提示: 来自行

If I just copy and paste the contents of logic.js onto the end of main.js it's fine...

我了解 logic.js 函数使用 main.js 数据。 如果是这样,您需要重新排序 html 中的 js 加载。 ```

```