The “cannot access before initialization” reference error occurs in JavaScript when you try to access a variable before it is declared with let or const and initialized in the same scope. To fix it, initialize the variables before accessing them.

Here are some examples of the error occurring:
// ❌ ReferenceError: Cannot access 'num' before initialization
console.log(num);
let num = 2;
// ❌ ReferenceError: Cannot access 'name' before initialization
console.log(name);
const name = 'Coding Beauty';
// ❌ ReferenceError: Cannot access 'arr' before initialization
arr = [7, 8, 9];
let arr = [3, 4, 5];
To solve the error, you need to initialize the variable before accessing it.
// ✅ No error
let num = 2;
console.log(num); // 2
// ✅ No error
const name = 'Coding Beauty';
console.log(name); // Coding Beauty
// ✅ No error
let arr = [3, 4, 5];
arr = [7, 8, 9];
var vs let
The occurrence of this error shows an important difference between the var and let keywords. If you had declared the variable with var, the error wouldn’t have occurred.
// No error
console.log(num); // undefined
var num = 2;
// No error
console.log(name); // undefined
var name = 'Coding Beauty';
// No error
arr = [7, 8, 9];
var arr = [3, 4, 5];
This happens because variables declared with the var keyword are hoisted – they are moved by the JavaScript interpreter to the top of the current scope (to the top of the current script or current function).
Basically, this is what happens to our variables declared with var:
var num;
var name;
var arr;
console.log(num); // undefined
num = 2;
console.log(name); // undefined
name = 'Coding Beauty';
arr = [7, 8, 9];
arr = [3, 4, 5];
Note: The declarations are hoisted, but the initializations are not.
Because of this hoisting, even when the variable is declared in a non-function block, like an if block, the error will still not occur if you try to access the variable from outside the if statement.
// No error!
console.log(num); // undefined
if (true) {
var num = 2;
}
Only the global scope and function scopes are used for hoisting, so like before, the variable declaration is moved to the top of the file.
var num;
console.log(num); // undefined
if (true) {
num = 2;
}
11 Amazing New JavaScript Features in ES13
This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.

Sign up and receive a free copy immediately.

Ayibatari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.
None of the answers above solved my problem, so here’s my solution:
var mockMyMethod: jest.Mock;
jest.mock('some-package', () => ({
myMethod: mockMyMethod
}));
Something about using const before the imports feels weird to me. The thing is: jest.mock is hoisted. To be able to use a variable before it you need to use var, because it is hoisted as well. It doesn’t work with let and const because they aren’t.
answered Jun 21, 2021 at 19:31
4
The accepted answer does not handle when you need to spy on the const declaration, as it is defined inside the module factory scope.
For me, the module factory needs to be above any import statement that eventually imports the thing you want to mock.
Here is a code snippet using a nestjs with prisma library.
// app.e2e.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import mockPrismaClient from './utils/mockPrismaClient'; // you can assert, spy, etc. on this object in your test suites.
// must define this above the `AppModule` import, otherwise the ReferenceError is raised.
jest.mock('@prisma/client', () => {
return {
PrismaClient: jest.fn().mockImplementation(() => mockPrismaClient),
};
});
import { AppModule } from './../src/app.module'; // somwhere here, the prisma is imported
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
)};
answered Apr 15, 2021 at 19:07
![]()
JasonJason
2744 silver badges5 bronze badges
3
To clarify what Jason Limantoro said, move the const above where the module is imported:
const mockMethod1 = jest.fn(); // Defined here before import.
const mockMethod2 = jest.fn();
import MyClass from './my_class'; // Imported here.
import * as anotherClass from './another_class';
jest.mock('./my_class', () => {
return {
default: {
staticMethod: jest.fn().mockReturnValue(
{
method1: mockMethod1,
method2: mockMethod2,
})
}
}
});
answered May 19, 2021 at 0:49
MattMatt
4,2014 gold badges38 silver badges56 bronze badges
The problem that the documentation addresses is that jest.mock is hoisted but const declaration is not. This results in factory function being evaluated at the time when mocked module is imported and a variable being in temporal dead zone.
If it’s necessary to access nested mocked functions, they need to be exposed as a part of export object:
jest.mock('./my_class', () => {
const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();
return {
__esModule: true,
mockMethod1,
mockMethod2,
default: {
...
This also applies to manual mocks in __mocks__ where variables are accessible inside a mock only.
answered Jan 4, 2021 at 7:43
Estus FlaskEstus Flask
203k70 gold badges417 silver badges557 bronze badges
5
You should move your mocking above your imports; that could be the source of your issue. Imports are also hoisted, so multiple hoisted entries would be hoisted in order.
jest.mock('./my_class', () => {
const mockMethod = jest.fn()
const default = { staticMethod: jest.fn().mockReturnValue({ method: mockMethod }) };
return { default, mockMethod };
});
import MyClass, { mockMethod } from './my_class'; // will import your mock
import * as anotherClass from './another_class';
However, if you for some reason can’t do that, you could use doMock to avoid hoisting behaviour. If this happens on the top of your file, it should be a 1 to 1 change.
const mockMyMethod = jest.fn();
jest.doMock('some-package', () => ({ myMethod: mockMyMethod }));
answered Aug 1, 2022 at 3:57
![]()
Ricardo NoldeRicardo Nolde
33.2k4 gold badges36 silver badges40 bronze badges
1
This solution works for me and it’s pretty easy for vuejs+ jest.
Two points to note:
- you should declare the absolute path and not ‘@/js/network/repositories’
- the getter helps to defer the instantiation
const mockGetNextStatuses = jest.fn();
const mockUpdatePrintingStatus = jest.fn();
jest.mock('../../../../../../src/js/network/repositories/index.js', () => {
return {
get printing() {
return {
getNextStatuses: mockGetNextStatuses,
updatePrintingStatus: mockUpdatePrintingStatus,
}
}
}
});
or
jest.mock('../../../../../../src/js/network/repositories/index.js', () => ({
printing: {
getNextStatuses: jest.fn(),
updatePrintingStatus: jest.fn()
}
}));
import { printing } from '../../../../../../src/js/network/repositories/index.js';
// and mock the module
printing.getNextStatuses.mockReturnValue(['XX','YY']);
answered Aug 12, 2022 at 12:33
![]()
Per this article… Anyone making it to this page may just be able to set the mocked function to a function returning a function call. As per the OP’s code:
import MyClass from './my_class';
import * as anotherClass from './another_class';
const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();
jest.mock('./my_class', () => {
return {
default: {
staticMethod: jest.fn().mockReturnValue(
{
method1: () => mockMethod1(), // <- function returning function call
method2: () => mockMethod2(),
})
}
}
});
answered Apr 5 at 15:14
daleyjemdaleyjem
2,3051 gold badge23 silver badges34 bronze badges
This solution worked for me:
jest.mock("../user/useCases/GetUserBalancesUseCase.js", () => {
return {
GetUserBalancesUseCase: {
create: jest.fn().mockReturnValue({
execute: jest
.fn()
.mockReturnValue(require("./fixtures/user/useCaseResponse.js").useCaseResponse),
}),
},
}
})
I couldn’t use the fixture importing it using ESM syntax in this implementation. So I tried using require and fixed the import reference error issue.
This kind of mocking though, is not reliable because bypasses some logic that I want to have covered by the unit test. In my case is necessary to avoid interacting with the infrastructure.
As a reference, I need to test the output of an useCase given an input:
test("Get User Balances", async () => {
const useCaseResponse = await getUserBalancesUseCase.execute({ account, USDPrices })
expect(useCaseResponse).toEqual(getUserBalancesUseCaseResponse)
})
answered Apr 28 at 14:12
![]()
Example of using TypeScript with Jest and mockDebug.js module
jest.mock('debug', () => {
global.mockDebug = jest.fn();
return () => global.mockDebug;
});
// usage
describe('xxx', () => {
test('xxx', () => {
expect(global.mockDebug.mock.calls.toString()).toContain('ccc');
})
});
![]()
node_modules
4,7606 gold badges21 silver badges37 bronze badges
answered Nov 9, 2022 at 15:17
![]()
1
Время на прочтение
6 мин
Количество просмотров 9.4K
На первый взгляд, синтаксис JS прост и интуитивно понятен, что подкупает. Однако это не мешает тем, кто делает первые (или не первые) шаги в нём, допускать ошибки. Мы попытались осветить некоторые промахи начинающих разработчиков.
Язык JavaScript используется во фронтенд-разработке для браузерных приложений на стороне клиента. Для начала изучения достаточно простого редактора типа Notepad, браузера и какого-нибудь из многочисленных руководств для чайников. Но JavaScript проявляет себя не совсем так, как другие языки в разных ситуациях, и иногда это способствует возникновению ошибок. К примеру, нестрогая типизация языка и вольная трактовка данных может привести к тому, что данные будут интерпретироваться не так, как предполагает разработчик на этапе создания кода. Ошибки находятся в ходе работы этого кода.

Мария Кожанова
Программист и преподаватель
Переменная не определена либо недоступна в текущей области кода
Такое происходит сплошь и рядом — обращение к переменной, которая ранее не была объявлена либо недоступна в текущей области кода. Например, код:
<script>
let y = x + 1
</script>
Без предварительного определения переменной x породит ошибку.
Uncaught ReferenceError: x is not defined
Кроме того, переменная должна быть видна в текущем контексте. Сравните два примера.
Код 1.
<script>
function summa () {
let a = 2
let b = 3;
return a + b;
}
console.log(a); //Uncaught ReferenceError
</script>
Код 2.
<script>
let a = 2
let b = 3;
function summa () {
return a + b;
}
console.log(summa());
</script>
Код 1 на шестой строке выдаёт ошибку.
Uncaught ReferenceError: Cannot access 'a' before initialization
Дело в том, что переменная a определена внутри функции и недоступна за её пределами.
А код 2 без ошибок вернёт 5, потому что функция summa() имеет доступ ко всем переменным, определённым в глобальной области. Понимание области видимости важно в Javascript, области могут быть вложенными друг в друга, при этом дочерние области видимости будут иметь доступ к родительским, но не наоборот.
Неверно организовано условие сравнения if
Чтобы записать условие сравнения переменной с каким-либо значением, используется оператор ==.
<script>
if(x == some_value) {}
</script>
Однако если ошибиться и использовать одинарный знак =, то вместо сравнения в круглых скобках окажется присваивание.
<script>
if (x = some_value) {}
</script>
В JavaScript эта операция будет истинной, в то время как иные языки программирования могут среагировать ошибкой.
Подвид предыдущей ошибки — когда переменная сравнивается не просто со значением, а с конкретным — единицей.
<script>
var x = some_value;
if (x = 1) { … }
</script>
Тут дьявол в деталях. По-булевски единица — это истина, а ноль — ложь. В результате выражение будет истинно.
Сравнение значений разных типов
Иной раз сравниваются переменные, которым были присвоены значения разных типов.
<script>
x = prompt('Введите число:', 0);
y = prompt('Введите другое число:', 0);
if (y < x){
console.log("Первое число " + x + " больше " + y);
}
else if (y > x){
console.log("Второе число " + y + " больше " + x);
}
else if (x == y){
console.log(x + " равно " + y);
};
</script>
Ввожу 5 и 125, а мне в итоге пишут, что 5 больше 125, почему?
Отвечаем: в этом примере переменные x и y сравниваются как строки, а не как числа, так как после получения значений они так и остались строками.
Ситуация изменится, если приведём значения переменной к числу.
…
x = parseInt(x)
y = parseInt(y)
…
К слову, в коде полезен === . Это оператор строгого равенства, который проверяет сравнимое с учётом типов.
if(x === y) { … }
</script>
В этом фрагменте кода сравнение сразу вернёт ложь, если переменные разных типов.
Объявленные в цикле переменные не исчезают после его завершения
Следующий код нередко применяется в несложных сценариях, его любят начинающие разработчики.
<script>
for (let i = 0; i <= 100; i++) {
// некий код
}
console.log (i) //приведёт к выбросу исключения ReferenceError
</script>
Если попытаться использовать переменную i после выхода из цикла, то код в строке 4 приведёт к ошибке.
Переменная ликвидируется после окончания цикла, её значение будет не определено. В этом можно убедиться:
console.log(typeof i == typeof undefined) // выведет true
Попробуем при объявлении счётчика в цикле вместо let (это объявление переменной с блочной областью видимости) использовать директиву var.
<script>
for (var i = 0; i <= 100; i++) {
// некий код
}
console.log (i);
</script>
Тогда i после выхода из цикла продолжит жить своей жизнью.
Некорректное использование this
Ошибка возникает, когда специальное ключевое слово this отсутствует в коде либо используется неправильно. Ключевое слово this ссылается на контекст выполняемой функции. Оно помогает работать с объектами. Но имеет значение контекст — какой именно объект в данный момент кода будет описан словом this.
<script>
function myFunction() {
var myObject = {
objProperty: "текстовое свойство",
objMethod: function() {
console.log(objProperty); //код, который приведёт к ошибке
}
};
myObject.objMethod();
}
myFunction();
</script>
В строке 5 переменная objProperty не определена, код вернёт ошибку.
Uncaught ReferenceError: objProperty is not defined
А всё потому, что пропущено ключевое слово this. Если внутри объекта myObject требуется обратиться к значению его свойства, то это делается следующим образом: this.objProperty.
Другой пример:
<script>
Form.prototype.submit = function () {
this.clearLocalStorage();
this.timer = setTimeout(function() {
this.clearView(); //код, который приведёт к ошибке
}, 100);
};
</script>
Ключевое слово this на строке 4 употребляется, однако код вернёт ошибку.
Uncaught TypeError: this.clearView is not a function
В этой строке контекст для this — уже область функции setTimeout (объект window).
Чтобы достичь нужного контекста, следует обратиться к нему, сделать это можно разными путями:
-
Совместимым со старыми браузерами способом — определить выше переменную и использовать в нужный момент именно её.
…
var self = this;
this.timer = setTimeout(function() {
self.clearView();
}, 100);
…
-
Использовать метод bind(), который работает не в совсем старых версиях браузеров.
Form.prototype.submit = function () {
this.clearLocalStorage();
this.timer = setTimeout(this.countTime.bind(this), 100);
};
Form.prototype.countTime = function(){
this.clearView();
};
Использование alert
Это, скорее, не ошибка, а рекомендация более дружелюбного общения с посетителем. Чтобы мгновенно увидеть значение переменной value, можно просто взять и написать alert(value). Однако это не всегда поможет для решения сиюминутной проблемы. Например, если переменная value является объектом, то это мало что даст. Но существует набор решений для разных случаев.
Как правило, вывод данных нужен в ситуациях, когда хочется:
-
Что-то сказать посетителю, вывести информационное или предупредительное сообщение. Для этой цели применяют разные подходы с помощью jquery и bootstrap. К тому же в некоторых браузерах вывод данных с помощью
alertблокирует экран и не даёт ничего сделать на странице, пока этот алерт не отожмёшь. -
Произвести отладку в ходе разработки. В этом случае можно использовать объект браузера Console. Например,
console.log(value)выведет сообщение в веб-консоль.
Это лучше alert. Во-первых, как следует из названия, служебные данные выводятся в консоли. Туда заходит немного рядовых посетителей, и если вы вдруг забыли убрать отладочный вывод, его увидят далеко не все. Во-вторых, с помощью отладки в консоли можно детально смотреть на объекты, о чём вскользь упоминалось выше.
Зададим объект и посмотрим на него разными способами.
<script>
var Person = {
name: 'Peter', age: 34, skills: ['HTML', 'Javascript', 'CSS']
}
alert(Person)
console.log(Person)
</script>
Результат кода alert(Person).

И результат вывода в консоль. Как видите, более информативно.

Неверное подключение библиотек
Такое происходит, когда библиотеку:
-
не подключили,
-
не подключили вовремя, а библиотека или скрипт, которые в ней нуждаются, уже подключены/запущены.
И вместо галереи или слайдера поджидает ошибка.
Uncaught TypeError: Cannot read properties of undefined
Смотрим код.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.theme.default.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="owl-carousel">
<div class="item">
<h2>Item 1</h2>
</div>
<div class="item">
<h2>Item 2</h2>
</div>
<div class="item">
<h2>Item N</h2>
</div>
</div>
<script>
var owl = $('.owl-carousel');
owl.owlCarousel({...})
</script>
Библиотека Owl Carousel имеет в зависимостях Jquery, но подключается раньше.
В примере выше ошибку генерирует скрипт инициализации карусели.
Uncaught TypeError: owl.owlCarousel is not a function
У библиотеки не было шанса объявиться. Как правило, когда на странице используется ряд скриптов, ошибки плодятся как снежный ком.
Следует поменять местами подключения Jquery и Owl Carousel — строки 3 и 4.
Выводы
Избежать распространённых ошибок помогут практика и понимание того, как работает язык. Отследить баги помогут такие инструменты, как JSHint, JSLint, ESLint.
Кроме того, в IDE обычно имеются плагины для дебаггинга. В начале статьи мы говорили о том, что начинать изучение JavaScript можно с помощью редакторов типа Notepad. Но в удобной настроенной среде это делать гораздо приятнее и эффективнее.
Как вы слышали не раз, не ошибается тот, кто ничего не делает. Красное оповещение об ошибке в консоли не должно пугать. Это подсказка, что пошло не так, инструкция к действию — погуглить фразу Javascript <текст ошибки>.
There is a circular dependency in @effect-ts/system:
@effect-ts/system/_traced/esm/Layer/definitions.js exports LayerSuspend,
but before it does that it will import @effect-ts/system/_traced/esm/Managed,
which imports @effect-ts/system/_traced/esm/Managed/methods/api.js,
which imports @effect-ts/system/_traced/esm/Layer/core.js,
which imports LayerSuspend from @effect-ts/system/_traced/esm/Layer/definitions.js
(which is not finished yet, as it’s circular)
and uses LayerSuspend in initialization in this line:
export const Empty = /*#__PURE__*/ new LayerSuspend(() => identity()).
Note that most of these modules are flagged as side effect free and there are also a few /*#__PURE__*/ annotations, so a lot code might be dropped when optimizations are enabled, which could «fix» this code when e. g. the Empty export is unused.
Also note that execution order might change in side effect free modules even in development mode (side effects optimization is also enable in dev mode), so you might get different behavior. There are cases where code with circular dependencies depends on a certain execution order to work properly. This kind of code has an implicit side effect of putting some modules into the module cache.
Also note that when transpiling code from ESM to CJS, it might look like that «fixes» some of the circular dependencies as exports in circular dependencies might return undefined instead of throwing a ReferenceError.
Here is a simple example of this behavior: typescript playground. The typescript transpiled code logs undefined instead of throwing a ReferenceError.
The «ReferenceError: Cannot access ‘x’ before initialization» error in JavaScript occurs when a variable is used before it has been declared or assigned a value. This error often occurs in JavaScript testing frameworks, such as Jest, due to the way that variables are scoped within test files. Here are a few methods that can be used to resolve this error:
Method 1: Use «let» or «const» instead of «var»
To fix the ReferenceError: Cannot access '' before initialization error in Jest, you can replace the var keyword with let or const. This error occurs when you try to access a variable before it has been initialized. Using let or const ensures that the variable is initialized before it is accessed.
Here’s an example:
// Before
var myVar = 'Hello';
console.log(myVar);
// After
let myVar = 'Hello';
console.log(myVar);
You can also use const if you know that the variable will not be reassigned:
// Before
var PI = 3.14;
console.log(PI);
// After
const PI = 3.14;
console.log(PI);
If you need to reassign the variable, use let:
// Before
var count = 0;
count = count + 1;
console.log(count);
// After
let count = 0;
count = count + 1;
console.log(count);
In summary, using let or const instead of var helps to prevent the ReferenceError: Cannot access '' before initialization error in Jest.
Method 2: Use the «beforeEach» or «beforeAll» hooks
To fix the «ReferenceError: Cannot access » before initialization» error in Jest, you can use the «beforeEach» or «beforeAll» hooks to initialize the variable before running the test.
Here is an example using the «beforeEach» hook:
let myVar;
beforeEach(() => {
myVar = 'initialized';
});
describe('my test', () => {
test('myVar should be initialized', () => {
expect(myVar).toBe('initialized');
});
});
In this example, we declare the «myVar» variable outside of the «beforeEach» hook. Then, in the «beforeEach» hook, we initialize it to the value we want to test. Finally, in the test, we check that «myVar» has been correctly initialized.
Here is another example using the «beforeAll» hook:
let myVar;
beforeAll(() => {
myVar = 'initialized';
});
describe('my test', () => {
test('myVar should be initialized', () => {
expect(myVar).toBe('initialized');
});
});
In this example, we use the «beforeAll» hook instead of «beforeEach». The difference is that «beforeAll» is only executed once, before all the tests, while «beforeEach» is executed before each test.
Using these hooks to initialize variables before running tests can help you avoid the «ReferenceError: Cannot access » before initialization» error in Jest.
Method 3: Use the «global» object to declare global variables
To fix the ReferenceError: Cannot access '' before initialization error in Jest, you can use the global object to declare global variables. Here’s how to do it in a few simple steps:
- Declare your global variable using the
globalobject in your test file:
global.myVariable = 'some value';
- Use the global variable in your test:
test('my test', () => {
expect(myVariable).toBe('some value');
});
- Make sure to clean up the global variable after your test is done:
afterEach(() => {
delete global.myVariable;
});
That’s it! With these steps, you should be able to declare and use global variables in your Jest tests without encountering the ReferenceError: Cannot access '' before initialization error.
Method 4: Move variable declarations to the top of the file
To fix the ReferenceError: Cannot access '' before initialization error in Jest, one solution is to move variable declarations to the top of the file. This error occurs when a variable is accessed before it is initialized. By moving the variable declarations to the top of the file, we ensure that the variables are initialized before they are used.
Here is an example of how to move variable declarations to the top of the file:
let myVar = 'hello';
function myFunc() {
console.log(myVar);
}
myFunc();
// move variable declaration to the top of the file
let myVar;
// initialize variable
myVar = 'world';
In this example, we have a variable myVar that is used in the myFunc function before it is initialized. To fix this, we move the variable declaration to the top of the file and initialize it later.
Another example:
function myFunc() {
console.log(myVar);
}
// move variable declaration to the top of the file
let myVar;
myFunc();
// initialize variable
myVar = 'hello world';
In this example, we have a variable myVar that is used in the myFunc function before it is initialized. To fix this, we move the variable declaration to the top of the file and initialize it later.
By moving variable declarations to the top of the file, we ensure that the variables are initialized before they are used, thus avoiding the ReferenceError: Cannot access '' before initialization error.
