Javascript.RU

Конструкции языка. Обработка ошибок.

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/while-for.

Раздел иллюстрирует особенности управляющих конструкций javascript, таких как while/for, switch и обработку исключений.

Две формы while:

// проверка вначале
while(i<5) { … }
// условие потом
do { … } while (i<5)

И две принципиально разные формы for. Одна - обычная:

// заметьте - новая переменная объявлена тут же
for (var i=0;i<10;i++) {
   ...
}

Другая - итерация по свойствам объекта:

for(key in obj) {
  ... obj[key]
}

Можно исключить унаследованные свойства (т.е исключить из цикла прототип). Для этого используем функцию hasOwnProperty:

// цикл только по собственным свойствам
for(var key in obj) {
  if (obj.hasOwnProperty(key)) {
    … obj[key] …
  }
}

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

Метки действуют только для циклов и switch, т.е организовать полноценный goto через них нельзя Sad

На метку внешнего цикла можно перейти при помощи break/continue, вот пример:

// внешний цикл
outer: for(…) {
	…
	// внутренний цикл
	for (…) {
		…
		// можно вывалиться из внешнего цикла
		break outer;
		…
		// или перейти на следующую итерацию внешнего цикла
		continue outer;
		…
	}
}

В некоторых языках можно сделать только switch(число/строка).

В javascript же конструкция switch принимает совершенно любой объект. Перед switch, как и перед циклами можно ставить метку, и делать break/continue на внешнюю метку.

switch (obj) {
case "test":
	…
	break
case 5:
	…
	break outer
default: 
	…
}

With - специфическая конструкция javascript, самый известный ее аналог - with в Pascal/Delphi. Поэтому мы остановимся на ней подольше.

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

Более подробно тема видимости разобрана в статье функции Javascript, а здесь - разберем конкретно то, что с ней делает with.

Коротко - with берет объект и делает из него новую вложенную область видимости.

Например, в некоторой функции:

function go() {
...
var obj

// obj будет браться из текущей области видимости
obj.size = 5
...
}

Создадим тестовый объект, но не просто var obj, а более развернуто:

obj_size

(Более подробно об определении и свойствах объекта написано в разделе Объекты, ООП)

Если мы завернем любые операторы в блок with(obj), то все свойства будут первым делом искаться в obj, а уже потом - во внешней области видимости.

В этом примере свойства weight и size будут взяты из объекта obj:

with (obj) {
	// width/height берутся из найденного size
	return weight / (size.width + size.height)
}

А здесь - with делает область видимости из obj.size:

with (obj.size) {
	return width + height
}

В чем польза with? Как правило, его используют для упрощения синтаксиса, чтобы много раз не повторять объект.

Типичный пример из реальной жизни:

with (div.style) {
	if (!browser.isSafari) {
		position = 'absolute'
	}
	left = 0
	right = 0
	visibility = 'hidden'	
}

Напомню, что интерпретатор javascript ищет все переменные в ближайшей области видимости. Если не находит - ищет в следующей, и так далее - до глобальных переменных, т.е window.
Поэтому можно, например, делать конструкции типа такой:

with (obj) {
	with (size) {
		return weight / (width + height)
	}
}

Здесь переменные из разных областей видимости используются в одном выражении.

with javascript

Область видимости size находится внутри obj, поэтому интерпретатор будет искать weight так:

  1. сначала посмотрит weight в size
  2. не найдет там такой переменной
  3. посмотрит weight в obj
  4. использует weight из obj

Работа с with(obj) не эквивалентна работе напрямую с объектом obj, т.к никаких новых переменных добавить в obj нельзя.

Например, сделаем тестовый объект:

obj = {
	weight: 100
}

mwsnap010.jpg

Внутри with можно получить weight, и даже поменять его значение:

javascript with

Но вот при попытке добавить переменную возникнет проблема:

mwsnap012.jpg

Сам объект не поменялся, зато перезаписали глобальную переменную

alert(obj.size)   // => undefined
alert(window.size)   // => 10

У with есть одна большая проблема, из-за которой многие вообще рекомендуют забыть эту конструкцию.

А именно - внутри блока with абсолютно нельзя сказать, откуда будет взята та или иная переменная.

Выше разобран пример, когда weight ищется сначала в size, затем в obj, и потом - в глобальной области window.
Если переменной не окажется там, где она по плану должна быть, то она будет взята/изменена в другой области видимости, возможно даже в глобальной window.

Это приводит к трудноуловимым ошибкам, поэтому часто используют альтернативу: временную переменную.

mwsnap013.jpg

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

Работа с исключениями в javascript организована в типичном для языка стиле вседозволенности.

Абсолютно любой объект можно бросить в виде исключения:

try {
  ...
  throw {message: "Ого!"}
  ..
} catch (e) {
  alert("Ага, попался!")
}

Обычно бросают, все же, не простые объекты, а потомки встроенного класса Error:

throw new Error("connection down, server timeout")
// или сделать наследника Error:
throw new ConnectionError("server timeout")

Встроенный класс Error удобен для унификации проверки "a instanceof Error" и интероперабельности с другими библиотеками, так как ничего полезного в нем часто нет.

В Firefox у объекта Error есть полный бэктрейс в свойстве stack и еще масса полезных свойств:

// так можно быстро узнать стек без отладчика
alert( (new Error()).stack )

В IE тоже есть некоторые полезные свойства, а в Opera/Safari - на момент написания только message:

var e = new Error("hi")
alert(e.message)  // => "hi"

Поэтому, например, у меня созданы потомки (синтаксис фреймворка dojo):

// базовый класс для ошибок, со стеком (Firefox)
// сообщением message и дополнительной информацией extra
dojo.declare(
	"dojo.Error",
	Error,
	function(message, extra) {
		this.message = message;
		this.extra = extra;
		this.stack = (new Error()).stack;	
	}
)
// Потомок, имя ошибки хранится в name
// формат: dojo.declare(Имя, Родитель, Конструктор)
dojo.declare(
	"dojo.CommunicationError",
	dojo.Error,
	function() {
		this.name="CommunicationError";
	}
)

// еще потомок для примера
dojo.declare(
	"dojo.LockedError",
	dojo.Error,
	function() {
		this.name="LockedError";
	}
)
...

При перехвате исключений редко нужно перехватывать все подряд. Обычно - надо перехватить определенный класс исключений. Стандартный оператор catch такого не умеет, поэтому полный код обработки будет выглядить так:

try {
	… код ...
} catch(e) {
	// ловим нужное исключение
	if (e instanceof ConnectionError) {
		// обрабатываем его
		… reconnect …
	} else {
		// пробрасываем незнакомое исключение дальше
		throw e
	}
		
} finally {
	// блок finally выполняется всегда, 
	// вне зависимости - было исключение или нет
	… notifyUser() ..
}

В этом примере также присутствует блок finally, взятый в javascript из java. В стандартной схеме try..catch..finally, код из блока finally выполняется либо после try, если эксепшна нет, либо после catch, даже если эксепшн выпал наружу.

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


Автор: UFABET168GO (не зарегистрирован), дата: 17 ноября, 2023 - 14:22
#permalink

ทางเข้าufabet168 เว็บตรง เสถียร ใช้งานง่ายที่สุด


Автор: nathalie590 (не зарегистрирован), дата: 20 ноября, 2023 - 13:08
#permalink

You can also download latest APKs, like Zaxiusdomain


Автор: Jacob59042 (не зарегистрирован), дата: 20 ноября, 2023 - 13:15
#permalink

You can also download these injectors to enhance your MLBB game experience.


Автор: betflixvip (не зарегистрирован), дата: 20 ноября, 2023 - 13:33
#permalink

Great post! I am actually getting ready to across this information, is very helpful my friend. I also like to recommend a site that is all about buy telegram members. Keep up the good work you are doing here. betflixvip


Автор: sad (не зарегистрирован), дата: 21 ноября, 2023 - 18:17
#permalink

인천오피
I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work.


Автор: BIOBETGAMING (не зарегистрирован), дата: 14 декабря, 2023 - 05:15
#permalink

I will right away clutch your rss feed as I can not in finding your e-mail subscription hyperlink or e-newsletter service. Do you have any? Please let me recognize so that I may subscribe. Thanks.
biobet


Автор: Smithgamer43 (не зарегистрирован), дата: 17 декабря, 2023 - 01:37
#permalink

Download the latest gaming injector unlock all the gaming features without paying a single penny You will be able to get unlimited money, Gems, Skins and many more


Автор: DAVID SMITH45 (не зарегистрирован), дата: 17 декабря, 2023 - 01:39
#permalink

You can download the crazy plane landing on your gaming androids without paying any single penny. Get more gaming funs with all premium features.


Автор: NBS Reborn (не зарегистрирован), дата: 17 декабря, 2023 - 21:48
#permalink

If you are looking for the best ML tools then try NBS Reborn 2024. It will help you in several ways like unlock skins, effects, emotes and many more.


Автор: Geddom (не зарегистрирован), дата: 30 декабря, 2023 - 10:12
#permalink

Cash App APK: A Definitive Guide for Safe Downloads and Usage. The digital age has brought forth convenient methods for handling financial transactions, and Cash App stands as a prime example of simplifying monetary exchanges. However, when it comes to downloading the Cash App APK, ensuring safety becomes paramount.

https://geddom.com/cash-app-apk-a-definitive-guide-for-safe-downloads-an...


Автор: Cash app Apk (не зарегистрирован), дата: 30 декабря, 2023 - 10:13
#permalink

Автор: Гость (не зарегистрирован), дата: 23 января, 2024 - 15:58
#permalink

Increase image size with image size increaser in kb free of cost with just a single click


Автор: ali khan (не зарегистрирован), дата: 15 марта, 2024 - 12:24
#permalink

Try it out today, and see how quick and good it is to improve your pictures without sacrificing the image quality. Our tool to increase image size in kb totally free, safe, and easy to use so that you complete your task easily.


Автор: one cargo (не зарегистрирован), дата: 9 апреля, 2024 - 16:31
#permalink

THE ONE CARGO ชิปปิ้ง บริการนำเข้าสินค้าจากจีนราคาถูก ทางเรามีบริการตั้งแต่จัดหา สั่งซื้อสินค้าจาก taobao 1688 Tmall ทุกเวบไซด์ในจีน และติดต่อโรงงานตามความต้องการของลูกค้า สะดวก รวดเร็วไม่มีขั้นต่ำ คิดตามจริง ไม่มีบวกเพิ่ม มีระบบสั่งซื้อออนไลน์ใช้งานง่ายและทันสมัย สามารถเช็คสถานะสินค้าได้ตลอด 24 ชม.


Автор: arceusx.bar (не зарегистрирован), дата: 3 июня, 2024 - 17:26
#permalink

Oh my goodness! Impressive article dude! Thank you so much, However I am going through issues with your RSS. I don’t know why I cannot subscribe to it. Is there anybody else getting the same RSS problems? Anyone who knows the answer can you kindly respond? Thanx!! https://arceusx.bar/


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
16 + 1 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum