Invalid left-hand side in assignment

Типы ошибок

Последнее обновление: 30.08.2021

Invalid left-hand side in assignment

В блоке мы можем получить информацию об ошибке, которая представляет объект. Все ошибки, которые генерируются интерретатором JavaScript,
предоставляют объект типа , который имеет ряд свойств:

  • : сообщение об ошибке

  • : тип ошибки

Стоит отметить, что отдельные браузеры поддерживают еще ряд свойств, но их поведение в зависимости от браузера может отличаться:

  • : название файла с кодом JavaScript, где произошла ошибка

  • : строка в файле, где произошла ошибка

  • : столбец в строке, где произошла ошибка

  • : стек ошибки

Получим данные ошибки, например, при вызове несуществующей функции:

try{
	callSomeFunc();
}
catch(error){
	console.log("Тип ошибки:", error.name);
	console.log("Ошибка:", error.message);
}
Тип ошибки: ReferenceError
Ошибка: callSomeFunc is not defined

Типы ошибок

Выше мы рассмотрели, что генерируемая интерпретатором ошибка представляет тип Error, однако при вызове несуществующей функции
генерируется ошибка типа . Дело в том, что тип Error представляет общий тип ошибок. В то же время есть конкретные типы ошибок для определенных ситуаций:

  • : представляет ошибку, которая генерируется при выполнении глобальной функции eval()

  • : ошибка генерируется, если параметр или переменная, представляют число, которое находится вне некотоого допустимого диапазона

  • : ошибка генерируется при обращении к несуществующей ссылке

  • : представляет ошибку синтаксиса

  • : ошибка генерируется, если значение переменной или параметра представляют некорректный тип или пр попытке изменить значение, которое нельзя изменять

  • : ошибка генерируется при передаче функциям encodeURI() и decodeURI() некорректных значений

  • : предоставляет ошибку, которая объединяет несколько возникших ошибок

Например, при попытке присвоить константе второй раз значение, генерируется ошибка TypeError:

try{
	const num = 9;
	num = 7;
}
catch(error){
	console.log(error.name);		// TypeError
	console.log(error.message);		// Assignment to constant variable.
}

Применение типов ошибок

При генерации ошибок мы можем использовать встроенные типы ошибок. Например:

class Person{
 
    constructor(name, age){
		if(age < 0) throw new Error("Возраст должен быть положительным");
        this.name = name;
        this.age = age;
    }
	print(){ console.log(`Name: ${this.name}  Age: ${this.age}`);}
}
	
try{
	const tom = new Person("Tom", -45);
	tom.print();
}
catch(error){	
	console.log(error.message);	// Возраст должен быть положительным
}

Здесь конструктор класса Person принимает значения для имени и возаста человека. Если передан отрицательный возраст, то генерируем ошибку в виде объекта Error. В качестве параметра в
конструктор Error передается сообщение об ошибке:

if(age < 0) throw new Error("Возраст должен быть положительным");

В итоге при обработке исключения в блоке catch мы сможем получить переданное сообщение об ошибке.

Все остальные типы ошибок в качестве первого параметра в конструкторе также принимают сообщение об ошибке. Так, сгенерируем несколько типов ошибок:

class Person{
 
    constructor(pName, pAge){
		
		const age = parseInt(pAge);
		if(isNaN(age))	throw new TypeError("Возраст должен представлять число");
		if(age < 0 || age > 120) throw new RangeError("Возраст должен быть больше 0 и меньше 120");
        this.name = pName;
        this.age = age;
    }
	print(){ console.log(`Name: ${this.name}  Age: ${this.age}`);}
}

Поскольку для возраста можно ередатьне только число, но и вообще какое угодно значение, то вначале мы пытаемся преобразовать это значение в число с помощью
функции parseInt():

const age = parseInt(pAge);
if(isNaN(age))	throw new TypeError("Возраст должен представлять число");

Далее с помощью функции isNaN(age) проверяем, является полученное число числом. Если age – НЕ число, то данная функция возвращает true. Поэтому
генерируется ошибка типа TypeError.

Затем проверяем, что полученное число входит в допустимый диапазон. Если же не входит, генерируем ошибку типа RangeError:

if(age < 0 || age > 120) throw new RangeError("Возраст должен быть больше 0 и меньше 120");

Проверим генерацию исключений:

try{
	const tom = new Person("Tom", -45);
}
catch(error){	
	console.log(error.message);	// Возраст должен быть больше 0 и меньше 120
}

try{
	const bob = new Person("Bob", "bla bla");
}
catch(error){	
	console.log(error.message);	// Возраст должен представлять число
}

try{
	const sam = new Person("Sam", 23);
	sam.print();	// Name: Sam  Age: 23
}
catch(error){	
	console.log(error.message);
}
Возраст должен быть больше 0 и меньше 120
Возраст должен представлять число
Name: Sam  Age: 23

Обработка нескольких типов ошибок

При выполнении одного и то же кода могут генерироваться ошибки разных типов. И иногда бывает необходимо разграничить обработку разных типов.
В этом случае мы можем проверять тип возникшей ошибки. Например, пример выше с классом Person:

class Person{
 
    constructor(pName, pAge){
		
		const age = parseInt(pAge);
		if(isNaN(age))	throw new TypeError("Возраст должен представлять число");
		if(age < 0 || age > 120) throw new RangeError("Возраст должен быть больше 0 и меньше 120");
        this.name = pName;
        this.age = age;
    }
	print(){ console.log(`Name: ${this.name}  Age: ${this.age}`);}
}
	
try{
	const tom = new Person("Tom", -45);
	const bob = new Person("Bob", "bla bla");
}
catch(error){	
	if (error instanceof TypeError) {
		console.log("Некорректный тип данных.");
	} else if (error instanceof RangeError) {
		console.log("Недопустимое значение");
	}
	console.log(error.message);
}

Создание своих типов ошибок

Мы не ограничены встроенными только встроенными типами ошибок и при необходимости можем создавать свои типы ошибок, предназначеные для каких-то конкретных ситуаций.
Например:

class PersonError extends Error {
  constructor(value, ...params) {
    // остальные параметры передаем в конструктор базового класса
    super(...params)
    this.name = "PersonError"
    this.argument = value;
  }
}

class Person{
 
    constructor(pName, pAge){
		
		const age = parseInt(pAge);
		if(isNaN(age))	throw new PersonError(pAge, "Возраст должен представлять число");
		if(age < 0 || age > 120) throw new PersonError(pAge, "Возраст должен быть больше 0 и меньше 120");
        this.name = pName;
        this.age = age;
    }
	print(){ console.log(`Name: ${this.name}  Age: ${this.age}`);}
}
	
try{
	//const tom = new Person("Tom", -45);
	const bob = new Person("Bob", "bla bla");
}
catch(error){	
	if (error instanceof PersonError) {
		console.log("Ошибка типа Person. Некорректное значение:", error.argument);
	}
	console.log(error.message);
}
Ошибка типа Person. Некорректное значение: bla bla
Возраст должен представлять число

Для представления ошибки класса Person здесь определен тип PersonError, который наследуется от класса Error:

class PersonError extends Error {
  constructor(value, ...params) {
    // остальные параметры передаем в конструктор базового класса
    super(...params)
    this.name = "PersonError"
    this.argument = value;
  }
}

В конструкторе мы определяем дополнительное свойство – argument. Оно будет хранить значение, которое вызвало ошибку. С помощью параметра value конструктора
получаем это значение. Кроме того, переопреляем имя типа с помощью свойства this.name.

В классе Person используем этот тип, передавая в конструктор PersonError соответствующие значения:

if(isNaN(age))	throw new PersonError(pAge, "Возраст должен представлять число");
if(age < 0 || age > 120) throw new PersonError(pAge, "Возраст должен быть больше 0 и меньше 120");

Затем при обработки исключения мы можем проверить тип, и если он представляет класс PersonError, то обратиться к его свойству argument:

catch(error){	
	if (error instanceof PersonError) {
		console.log("Ошибка типа Person. Некорректное значение:", error.argument);
	}
	console.log(error.message);
}

new ()
new (message)
new (message, options)
new (message, fileName)
new (message, fileName, lineNumber)

()
(message)
(message, options)
(message, fileName)
(message, fileName, lineNumber)

new , так и без него . Оба создают новый экземпляр ReferenceError .

Человеческое описание ошибки.

Объект,обладающий следующими свойствами:

Свойство,указывающее на конкретную причину ошибки.При перехвате и повторном отбрасывании ошибки с более конкретным или полезным сообщением об ошибке это свойство можно использовать для передачи исходной ошибки.

Имя файла,содержащего код,который вызвал исключение.

Номер строки кода,вызвавшего исключение

Поймать ошибку в ссылке

 {
   a = undefinedVariable
}  (e) {
  .(e  )  
  .(e.)                    
  .(e.)                       
  .(e.)                   
  .(e.)                 
  .(e.)               
  .(e.)                      
}

Создание ссылочной ошибки

 {
    (, , )
}  (e) {
  .(e  )  
  .(e.)                    
  .(e.)                       
  .(e.)                   
  .(e.)                 
  .(e.)               
  .(e.)                      
}

Browser compatibility



JavaScript



Поймать ошибку в ссылке

 {
   a = undefinedVariable
}  (e) {
  .(e  )  
  .(e.)                    
  .(e.)                       
  .(e.)                   
  .(e.)                 
  .(e.)               
  .(e.)                      
}

Создание ссылочной ошибки

 {
    (, , )
}  (e) {
  .(e  )  
  .(e.)                    
  .(e.)                       
  .(e.)                   
  .(e.)                 
  .(e.)               
  .(e.)                      
}

Browser compatibility



JavaScript



“x” не определено

    defined (V8-based & Firefox)
 Can

Что пошло не так?

области .

<script> , загружающий библиотеку, перед кодом, который его использует.

Читайте также:  КОД ОШИБКИ 104 ЧТО ДЕЛАТЬ

Переменная не объявлена

String.prototype.substring() работал.

 foo = ;
foo.substring(); 

функции, не могут быть доступны из любого места за пределами функции, потому что переменная определяется только в области видимости функции.

 () {
   num1 = ;
   num2 = ;
   num1 + num2;
}

.(num1); 

Однако функция может получить доступ ко всем переменным и функциям,определенным в области видимости,в которой она определена.Другими словами,функция,определенная в глобальной области видимости,может получить доступ ко всем переменным,определенным в глобальной области видимости.

 num1 = ;
 num2 = ;

 () {
   num1 + num2;
}

.(()); 



JavaScript



Ситуация: нам нужно быстро дописать код, но не хватает одной функции. Мы не знаем, как её быстро реализовать, поэтому идём за ней в интернет — и находим:

// складываем два числа, которые на самом деле — строки; возвращаем строку
function plus(a,b) {
// тут будет результат
    var result = '';
    // переводим строки в числа
    x = parseInt(a);
    y = parseInt(b);
    // получаем результат
    result += x + y;
    // и возвращаем ответ в виде строки
    return(String(result));
}

console.log(plus(x,y));

Внешне вроде всё хорошо, но при запуске компьютер выдаёт ошибку:

❌ReferenceError: Can’t find variable: x

Откуда ошибка, ведь все переменные у нас есть?

Что это значит: JavaScript встретил переменную, которую ему сказали использовать, но он не знает, где её брать. В нашем случае это происходит в последней строке: console.log(plus(x,y)); — мы сказали «выведи в консоль результат сложения X и Y», но не сказали, что это за икс и игрек. 

Возможно, автор исходного кода имел в виду, что у вас где-то ранее эти переменные определяются; или что вы будете использовать последнюю строку для отладки на тестовых данных. В любом случае он не предусмотрел, что эти переменные у вас могут быть не определены.

Что делать с ошибкой ReferenceError

Чтобы исправить ошибку, нужно определить переменную до того, как вы её начн`те использовать. Например: 

let x = '11';
let y = '12';
console.log(plus(x,y));

 Если хотите, можно спросить значение у пользователя (коряво, но мы так иногда делаем):

let x = prompt("Введите первое число");
let y = prompt("Введите второе число");
console.log(plus(x,y));

Можно получить значение элементов веб-страницы, можно запросить их с сервера через асинхронный запрос. Это уже зависит от того, какая у вас страница. 

А ещё можно просто не использовать переменные, пока они не понадобятся. По сути, в нашем коде выше не было никакой необходимости выводить сумму чисел сразу после определения функции. Можно убрать последнюю строку с console.log() и жить спокойно. 

Где ещё

Иногда такая ошибка возникает при использовании специальных библиотечных функций в браузере или без предварительного импорта. Например, команда const axios = require("axios"); при запуске в браузере тоже выдаст ошибку, потому что эта команда предполагает запуск в среде Node.js, а не в браузере.

Представьте такое: вы делаете онлайн-калькулятор на JavaScript и хотите реализовать, например, функцию возведения в степень. Вы идёте в Яндекс, вбиваете в поиск «возведение в степень javascript». По первой строке в результатах всё понятно: нам нужна функция math.pow() из стандартной математической библиотеки math. Пишем код:

Читайте также:  MLab.org.ua

// возводим число Х в степень У и отправляем в переменную result

result = math.pow(x,y);

Этот код при запуске вываливается с ошибкой:

❌ ReferenceError: math is not defined

Это означает: «Я не знаю, что такое math, поэтому не буду это выполнять». При этом вы точно уверены, что всё в порядке, потому что все остальные сайты дают именно такую же команду.

Но всё проще, чем вы думаете.

Что делать с ошибкой ReferenceError

Дело в том, что в JavaScript все имена встроенных объектов пишутся с большой буквы. Math — тоже встроенный объект, поэтому его тоже нужно писать с большой буквы. Чтобы исправить нашу ошибку, этого будет достаточно:

// возводим число Х в степень У и отправляем в переменную result

result = Math.pow(x,y);

Теперь ошибки нет, и мы можем продолжать делать свой онлайн-калькулятор.

Объясните подробнее

JavaScript — регистрозависимый язык. Это значит, что он различает строчные и прописные буквы в названиях переменных, командах и функциях. Например, hello, Hello и HELLO — три разные переменные с точки зрения JavaScript.

По этой причине нужно перепроверять все команды, которые вы находите на любых сайтах — возможно, там есть ошибка в синтаксисе. А иногда программист просто забывает написать нужную команду с большой буквы. Такие дела.

Ситуация: вы пишете код, который обрабатывает нажатия на клавиши для управления в игре. Вы вспоминаете, что нужно сделать отдельную функцию для проверки на попадание в цель. Для этого вы хотите сравнить текущие координаты с координатами цели — если они совпадают, то есть попадание. В результате получается такой код:

Но при запуске игра падает с ошибкой:

❌ ReferenceError: Invalid left-hand side in assignment

Что случилось: браузер видит условный оператор if и хочет выполнить сравнения в скобках. Если равенство выполняется, то условие истинно и можно выполнить команду вывода на экран. Но вместо сравнения браузер встречает оператор присваивания, понимает, что ему тут не место, и останавливает программу.

Чтобы ошибки не было, нужно использовать не один знак равенства, а два. Один — присваивание, два — сравнение:

Когда встречается: когда мы делаем что-то не то с левой частью выражения — присваиваем вместо сравнения или перенаправляем вывод в переменную, которая не предназначена для такого. Ещё такая ошибка бывает, когда что-то пытаются присвоить ключевому слову this — оно хоть и похоже на переменную по поведению, но присваивать ему новое значение так нельзя.

Invalid left-hand side in assignment

Скорее всего, вы используете присваивание вместо сравнения. Это частая ошибка у новичков, потому что в математике знак «=» означает именно равенство.

Если дело не в этом, то вот вопросы, которые помогут вам с поиском ошибки:

  • можно ли вообще делать с этой переменной то, что вы делаете;
  • нужен ли отдельный модуль или компонент для выполнения этой команды и подключён ли он;
  • правильно ли вы используете эту команду или оператор — на всякий случай уточните и загляните в справочник.

Попробуйте сами

if (Math.PI = 3 || Math.PI = 4) { 
  console.log('Потрачено!');
}
var str = 'Привет, '
+= 'это журнал '
+= 'Код!';

Задание со звёздочкой: есть такой фрагмент кода на странице

<input type=»text» id=»number»><br>

Enter exponent:<br>

<input type=»text» id=»degree»><br><br><br>

<button id=»button»>Result</button>

<input type=»text» id=»result»>

И есть такой скрипт, который при нажатии на кнопку падает с нашей ошибкой:

var button = document.getElementById('button');
button.addEventListener('click', math);
 
function math(a,b){
    var a = document.getElementById('number').value;
    var b = document.getElementById('degree').value;
    var result = Math.pow(a,b);
    document.getElementById('result') = result;
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *