Основы JS по Флэнэгану;
Изучаю ща основы по Флэнэгану.
Многое непонятно. Сухо написано. Но подробно :) Может перевод еще добавляет. Тут буду постить возникшие по ходу изучения вопросы. Чтоб не засирать весь форум мелкими темками :) Прошу ответить, кто понял :) Ну или отправить по ссылке. Постараюсь структурировано спрашивать. Заранее всем спасибо! :) зы. сейчас нахожусь на регулярных выражениях (отэта Тема!) но многое было непонятно еще раньше. Я в тетрадку записал :) |
Ну к примеру в программах часто применяется спецификатор var при объявлении переменной, однако javascript, как было сказано достаточно лояльный язык и не ругнется и если мы будем использовать сразу переменную (без var-а). Так зачем его ставить?
|
var создаёт переменную в локальной области видимости, а так она создаётся в глобальной (window).
(function () { a = 0; var x = 0; })(); alert(a); // 0 alert(x); // нету |
var, строго говоря, создаёт переменную вообще, да ещё и в текущей области видимости. Без него будет не переменная, а свойство объекта window.
Не надо надеяться на лояльность языка, ногу себе отстрелите в самый неподходящий момент. |
а чем отличается локальная область видимости от текущей, и глобальная область видимости от свойств объекта window?
|
Посыл был, что без var переменная не создаётся вообще. Но это теоретическая сторона вопроса.
|
Инструкция var определяет каждую из перечисленных переменных путем создания свойства с этим именем в объекте вызова функции, в которой она находится, или в глобальном объекте, если объявление находится не в теле функции.
|
Отличия между var и без var:
<script type="text/javascript"> try { var a = 1; b = 1; delete a; delete b; alert(a); alert(b); } catch (e) { alert('Error: ' + e.message); } </script> |
Цитата:
Цитата:
|
--offtop: --
upd: Kolyaj вы теперь в Yandex'e? |
Да.
|
прикольно :)
|
Цитата:
получается б толком не удалилась? как это соотносится с отличиями в создании переменной? хм, ну теоретически я понял впрочем.:) |
как раз b удалилась
var a = 1; b = 2; alert([window['a'], window['b']]); без var в window создается соответствующее свойство |
x-yuri,
а теперь понял. Т.е. с варом получается этакая независимая (от глобального объекта) переменная? |
Цитата:
|
Всем привет, всех с прошедшим! (:
Тоже недавно начал изучать Флэнагана, поэтому решил втиснуться с вопросами в эту темку, надеюсь автор топика не будет против. ;) К сути: Прочитал про разницу в работе с переменными "по значению" и "по ссылке" и возник вопрос по строкам - для "иллюстрации" передачи элементарных типов по значению Флэнаган применяет такой код: var a = 3; var b = a; a = 4; alert(b); // показывает 3 Но он говорит что строки в js неизменяемы и поэтому проверить как они передаются (по ссылке или по значению) невозможно, т.к. аналогичный код для строк не будет работать, хотя можно установить что сравниваются они по значению: var s1 = "text"; var s2 = "tex" + "t"; alert(s1 == s2); // true Но у меня возник вопрос, а что все-таки мешает сделать для строк такую проверку: var str1 = "bunny"; var str2 = str1; str1 = "rabbid"; alert(str2);// показывает bunny По идее это показывает что строки копируются по значению, в чем тут тогда загвостка? P.S. Кстати, почему во втором отрывке кода нет нумерации строк? Тот же тэг JS использовал... P.P.S. Подумал, посидел, еще подумал, почитал немного дальше и пришла в голову такая мысль - получается что в описанном мною примере в str1 содержится не строка bunny, а ссылка на неё, а при "присваивании" ей новой строки "rabbid" мы создаем эту новую строку и в str1 записываем ссылку на неё, а в str2 у нас просто ссылка на первую строку, которая не удалилась, т.к. на неё еще есть "активная" ссылка. Что-то в этом роде? |
Kepa,
все переменные в JS передаются по значению. Просто в случае объектов значением является ссылка на объект. Это сначала трудно осознать, но потом всё встаёт на свои места. http://dmitrysoshnikov.com/ecmascrip...tion-strategy/ |
Числа и строки - элементарный тип данных и передаются они по значению.
А происходит это потому, что ссылочные типы данных не имеют фиксировнного размера и не могут храниться в выделенных 8 байтах памяти. var a = '10', b = '10'; alert(a*b); //100 выполняем операцию умножения со строковыми операндами, результат которых будет преобразован в числовое значение. var a = '10', b = '10'; alert(parseInt(a)+parseInt(b)); //20 выполняем операцию сложения со строковыми операндами, результат которых будет преобразован в числовое значение. Метод parseInt() преобразует значение в числовое, т.к. опрератор + может работать как со строками так и с числами Цитата:
|
Цитата:
var a = '10', b = '10'; alert(a+b); //20 выполняем операцию сложения со строковыми операндами, результат которых будет преобразован в числовое значение. |
Kolyaj я думал знак умножение поставил, а 20 вроде стер, т.к. из другого примера (поторопился, забыл parseInt) :D
upd: поправил |
Ок, спасибо за ответы (:
P.S. Цитата:
var a = '10', b = '10'; alert(+a+(+b)); |
Цитата:
alert(parseInt('1число')+parseInt('2число')); Цитата:
var a = '10', b = '10'; alert(+a+~~b); |
Цитата:
Это мы не проходили, это нам не задавали... |
Kepa в книжке, о которой идет речь, есть раздел "Побитовые операторы"
|
Я пока на 78-ой странице из 950, потихонечку доберемся и до них. (:
|
Цитата:
и непонятно, какое отношение имеют твои примеры к передаче параметров в функции... Цитата:
|
Цитата:
Цитата:
|
в первую очередь, я имел в виду, что про 8 байт - это не причина:
Цитата:
в-третьих, не важно, как она это делает в-четвертых, отдельная история уже не актуальна |
Пока вы спорите у меня возник новый вопрос :)
Прочитал про поразрядное НЕ (~) и у меня возникло недопонимание - как именно представляются отрицательные целые числа (http://javascript.ru/bitwise-operators - эту статью я тоже читал, но все равно до конца так и не понял), поясню: Число у нас представляется 32 разрядами, при этом старший (левый) разряд - знаковый, т.е. у нас диапазон чисел, если я правильно понял, от (2^31 - 1) до -(2^31). Далее, как представляются целые положительные числа в двоичной системе мне понятно, 1=1; 2=10; 3=11; 4=100; и т.д., при этом все разряды левее старшей единицы равны 0, а вот как представляются отрицательные мне уже непонятно, ну за тем исключением что старший бит равен 1. Возьмем пример из статьи: 314 = 00000000000000000000000100111010 -314 = 11111111111111111111111011000110 Так вот, что мне здесь непонятно - по какому алгоритму во втором случае мы "получаем" из этой последовательности -314, например мне было бы понятен такой вариант: -314 = 10000000000000000000000100111010 Но насколько я понимаю он понятен человеку, но очень неудобен для "компьютера" в вычислениях (а может и вообще непригоден), в таком случае мне был бы еще понятен вариант такой: -314 = 11111111111111111111111011000101 Т.е. это ~314, без "дополнения до двойки" - здесь я бы понимал что мы "получаем" -314 как разность максимального числа (все разряды равны 1) и 314, а старший бит указывает что число отрицательное, но в статье говорится что надо еще прибавить единицу, и вот тут я не понимаю, откуда берется эта единица и почему полученный после "дополнения до двойки" результат будет -314. В целом я подозреваю что тут что-то завязано с арифметикой целых чисел (например, если знаковый бит считать за обычный, то (0-1) будет равно максимальному числу, скажем для 8-ми разрядного без знакового представления 0-1 = 255. Будет здорово если кто-нибудь разжует данный момент (: P.S. Пока писал еще пришла мысль что это может быть связано с тем что у нас нет "отрицательного" нуля и поэтому у нас отрицательных чисел на одно больше чем положительных, может дело в этом? В любом случае хочется точно знать. :) |
~ - унарный оператор, который выполняет порязрядное инвертирование, в т.е. ~1 == 0, ~0 == 1.
Цитата:
|
Цитата:
Цитата:
-314 = 10000000000000000000000100111010 Как такое может быть менее понятно для человека, чем порязрядное отрицание с дополнением до двойки -314 = 11111111111111111111111011000110 я не понимаю, может я вхожу в число тех нескольких индивидуумов? ;) |
Цитата:
откуда берется единица: -0010 = 10000 - 0010 = 1111 - 0010 + 0001 = ~0010 + 0001 фактически, в случае ones' complement мы выбираем в качестве нуля 01111, а в случае two's complement - 10000, т.е. на единицу большее число. В результате (two's complement): у нас один ноль, не надо добавлять к результату бит переноса |
а объяснить все это можно, думаю, так:
нам надо вычесть 0001 (1) из 0010 (2), но мы хотим избавиться от вычитания, т.е. сделать это используя операцию сложения. Отметим, что xxxx + 10000 = xxxx. Тогда 0010 - 0001 = 0010 + 10000 - 0001 = 0010 + <two's complement of 0001> p.s. это бытовое объяснение на пальцах, и я не в курсе как оно видится с точки зрения представителей академической науки |
Цитата:
1. Ситуацию с циклом for: видимо есть какой то шаблон (каркас), на котором можно реализовывать различные варианты циклов for: ( in )? (firstChild, !=null, nextSibling). В частности как работает вариант с firstChild, nextSibling? 2. Все таки ситуацию с sort()-ом, не понять: 2.1 Сравнивающая функция может иметь только 2 аргумента? 2.2 Эти m и n ни что иное как l и r в QuickSort? Как вообще лучше читать такие сорты? А то у меня мозг перегревается их анализировать :) |
x-yuri,
Спасибо, более-менее разобрался (: |
Цитата:
for(<инициализация>;<условие>;<корректирование>){ //тело цикла } Цикл начинает работу (ищит следущий дочерний элемент e) с выражения x = e.firstChild, и работает до тех пор пока не получит значение null (как доберется до несущестующего элемента - e.lastChild+1) Может этот вариант поможет понять: <script type="text/javascript"> window.onload = function(){ var element = document.getElementById('div'), //родительский элемент children = element.childNodes, //дочернии элементы i = children.length, array = []; //получаем количество элементов и создаем пустой массив if(element.hasChildNodes()) { //проверяем есть ли дочернии элементы while(i--){ if(children[i].tagName != undefined) { //отбираем, только те которые не имеют значение undefined array.push(children[i].tagName + ': ' +children[i].innerHTML + '\n'); //добавляем в массив } } } alert(array.join('')); }; </script> <div id="div"> <div>0</div> <div>1</div> <div>2</div> </div> тоже самое (без линих проверок), только пошустрей: var element = document.getElementById('div').childNodes, i = element.length, array = []; while(i--){ array.push(element[i].nodeType == 1 ? element[i].innerHTML + '\n' : ''); } alert(array.join('')); |
<!DOCTYPE HTML> <html> <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/mootools/1.3.0/mootools-yui-compressed.js"></script> </head> <body> <ul id="list"> <li>один<li>два<li>три<li>четыре<li>пять </ul> <button>Сортировать</button> <script> $$('button').addEvent('click', function(){ $('list').getChildren() .sort(function(a, b){ if( a.get('text') == b.get('text') ) return 0; return a.get('text') < b.get('text') ? -1 : 1; }) .inject( $('list') ); }); </script> </body> </html> --- var element = document.getElementById('div'), //родительский элемент children = element.childNodes, //дочернии элементы i = children.length, array = []; //получаем количество элементов и создаем пустой массив if(element.hasChildNodes()) { //проверяем есть ли дочернии элементы while(i--){ if(children[i].tagName != undefined) { //отбираем, только те которые не имеют значение undefined array.push(children[i].tagName + ': ' +children[i].innerHTML + '\n'); //добавляем в массив } } } может в каких-нибудь фреймворках такой код и имеет смысл, но только не в real life... Цитата:
Цитата:
Цитата:
|
Цитата:
|
Цитата:
http://javascript.ru/ecma/part8#a-8.5 Цитата:
|
Часовой пояс GMT +3, время: 10:47. |