Javascript typeof выбрасывает referenceerror - PullRequest
3 голосов
/ 20 февраля 2020

позволяет сразу перейти к нему.
Я использую typeof, чтобы проверить, существует ли переменный API. Я узнал, что typeof возвращает «неопределенное», если переменная не существует.

function exitApplication() {
    let typeOfApi = typeof API;
    if (typeOfApi !== "undefined") {
        API.close(() => {
            strip.shutdown();
            ...
            ...
            ...
        });
    }
    else {
        console.log("Bye!");
        process.exit(0);
    }
}

Если я сейчас запускаю свою программу с тестовыми данными, что приводит к вызову exitApplication, когда API еще не определен Я получаю ReferenceError:

    let typeOfApi = typeof API;
                    ^

ReferenceError: API is not defined

Поскольку я использую Webpack, я изменил выходной файл и заменил API на что-то еще, что не было определено, и вуаля это работает, и typeOfApi является "неопределенным" (код I вставлено - это выход Webpack).

API - это значение const, и я использую только let и const в своем коде. Я читал кое-что о временных мертвых зонах, но typeof должен по-прежнему возвращать "undefined", если переменная let не определена?

Я также читал это Почему typeof только иногда выдает ReferenceError? , но я Я не использую выражение.

О, и мой код написан машинописным шрифтом. Но я не настолько хорош в этом и не знаю, как получить типы для restify, поэтому API имеет тип any. (Я знаю, что typeof и typecript - это совершенно разные вещи: D). Но код в любом случае переводится с 1 на 1.


Редактировать: Итак, я сделал этот маленький пример. Это вывод Webpack

#!/usr/local/bin/node
/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/        if(mode & 1) value = __webpack_require__(value);
/******/        if(mode & 8) return value;
/******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/        var ns = Object.create(null);
/******/        __webpack_require__.r(ns);
/******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/        return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./src/test.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./src/test.ts":
/*!*********************!*\
  !*** ./src/test.ts ***!
  \*********************/
/*! no static exports found */
/***/ (function(module, exports) {

exitApplication();
const API = {};
function exitApplication() {
    let typeOfApi = typeof API;
    console.log(typeOfApi);
    if (typeOfApi !== "undefined") {
        console.log("Bye!");
        process.exit(0);
    }
    else {
        console.log("Bye!");
        process.exit(0);
    }
}


/***/ })

/******/ });
//# sourceMappingURL=LED-Controller.js.map

И это также вызовет ошибку ошибки

Редактировать: Вот мои настройки TS и Webpack. https://gist.github.com/Lucarus/ebbfab5cc6560094a292ba86557ffd1d
Для примера я заменил Applications.ts на test.ts, но он использовал тот же конфиг.

1 Ответ

2 голосов
/ 20 февраля 2020

Вы вызываете функцию, которая ссылается на переменную const API = {} ДО того, как эта переменная была инициализирована, но внутри области, где она будет объявлена. С const и let это недопустимо. У вас есть это:

exitApplication();
const API = {};
function exitApplication() {
    let typeOfApi = typeof API;
    console.log(typeOfApi);
    if (typeOfApi !== "undefined") {
        console.log("Bye!");
        process.exit(0);
    }
    else {
        console.log("Bye!");
        process.exit(0);
    }
}

Функция поднята в верхнюю часть этой области, поэтому вы можете вызвать exitApplication(), но вы еще не выполнили строку кода, которая инициализирует API. Но интерпретатор знает, что он там и еще не инициализирован, и это ReferenceError в Javascript, чтобы попытаться получить доступ к определенной переменной const или let в области, где она определена до того, как будет запущена строка, содержащая ее объявление. .

Когда я запускаю это в Chrome, я получаю точную ошибку:

Uncaught ReferenceError: Cannot access 'API' before initialization

, которая точно говорит вам, в чем проблема. На первом проходе интерпретатора он проанализировал код и узнал, что const API = {} есть, поэтому доступ к нему запрещен до тех пор, пока он не достигнет той строки кода, которая его инициализирует. Если вы действительно хотите обойти это, измените const на var, но, вероятно, есть просто лучший способ написания кода, в котором не нужно использовать var.


Конечно, если вы просто переместите объявление API на одну строку, нет проблем:

const API = {};
exitApplication();
function exitApplication() {
    let typeOfApi = typeof API;
    console.log(typeOfApi);
    if (typeOfApi !== "undefined") {
        console.log("Bye!");
        process.exit(0);
    }
    else {
        console.log("Bye!");
        process.exit(0);
    }
}

Хорошую статью об этой теме c можно прочитать в этой статье: Почему typeof больше не безопасен .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...