LINUX.ORG.RU

за что мы любим javascript

 


0

1
for(var j = 0; j < 3; j++) {
  console.log('j1 %s', j)
  for(var j = 0; j < 3; j++) {
    console.log('j2 %s', j)
  }
}



результат

j1 0
j2 0
j2 1
j2 2


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

★★★★★

Ответ на: комментарий от int64

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

Но если этот код так активно использует глобальные переменные (я верно понял, речь о коде анонимуса с documentProxy?) — вряд ли его там будет просто починить.

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

Слушай, симбиоз прямо.

Тема снова открыта. Спасибо.

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от AndreyKl

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

int64
()
Ответ на: комментарий от AndreyKl

использует глобальные переменные

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

Четко и ясно пислалось не раз - переменная из внешней области видимости. ВНЕШНЕЙ. Внешняя область видимости это не global state. Это внешняя область видимость, стоящая на уровень или несколько выше от текущей. Откуда импортируются переменные.

int64
()
Ответ на: комментарий от int64

Ну, язык то всё равно не очень, что тут сделаешь.

То что «у него было такое ТЗ» никак не может оправдать результат. Да, было. Я тут причём?

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от int64

ВНЕШНЕЙ. Внешняя область видимости это не global state. Это внешняя область видимость, стоящая на уровень или несколько выше от текущей. Откуда импортируются переменные.

а глобальная - не внешняя? и да, обычно это как раз глобальная, хоть завнешкайся.

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от int64

Язык замечательный.

неналюбуюсь прямо. то то всяких тайпскриптов за последний десяток лет родилось, начиная с darts-а заканчивая каким нибудь кложаскриптом. Видно людям тоже очень нравится. Ценят.

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от AndreyKl

Глобальная - это видимая отовсюду. Из любого места. В JS нет такого. Это в php, напимер, есть $GLOBALS который в лбом месте позволит получить доступ к глобальному скоупу. В js такого нет. У него есть только контексты и области видимости, которые вкладываются друг в друга. ГЛОБАЛЬНЫХ переменных в js нет.

int64
()
Ответ на: комментарий от AndreyKl

Так твое мнение и отношение к чем-либо это твой удел. Сиди страдай. Разве если бы ты не страдал, ходил бы жаловаться по форумам о чем-то?

int64
()
Ответ на: комментарий от AndreyKl

обычно это как раз глобальная, хоть завнешкайся

https://nodejs.org/dist/latest-v9.x/docs/api/vm.html#vm_vm_runincontext_code_...

Расскажи мне, как один и тот же скрипт вызванные в разных контекстах, сможет получить доступ к контексту другого (читай глобальной переменной), если программист не предсмотрит этого специально?

Ты осознаешь, что ты вообще не понимаешь как устроена объектная модель? И что такое динамическое программирование ты тоже не понимаешь.

int64
()
Ответ на: комментарий от AndreyKl

я не думаю, что я жопой написал.
Одна переменная для разных целей
нормальный код

\0
Не пиши никогда, ничего, ни на чём.

ты забыл добавить «и чтобы это был яваскрипт».

Тебе ответить на вопрос есть что?

То что в яваскрипте сделали таким странным поведение вар странно ставить мне в вину.

То есть ты язык не изучил, но виноват не ты.

crutch_master ★★★★★
()
Ответ на: комментарий от AndreyKl

По-моему, с появлением let можно было сделать var деприкейтед

Нет, не можно.

причин не понимаю

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

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

var такой, какой есть

Потому, что сначало ТЗ предполагало свистоперделки? А потом - программирование всего?
А потом годный движок автоматизации, управления памятью и т.п. ппонадобилось втиснуть в мало совместимый синтаксис?
Если тут все такие умные, чтож вы не верстаете в фп стиле, и не программируете опп на форте...

Shadow ★★★★★
()
Ответ на: комментарий от anonymous

а с let разве не будет работать?

Будет, но тогда стартовый пример следует писать

var j;

for(j = 0; j < 3; j++) {
  console.log('j1 %s', j)
  for(j = 0; j < 3; j++) {
    console.log('j2 %s', j)
  }
}
И уже как бы становится очевидно, что j одна и та же? Тогда в чём смысл нытья?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от int64

Язык замечательный.

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

anonymous
()
Ответ на: комментарий от int64

а начиная от транспайлеров, заканчивая динамическим метапрограммирование и патчингом самой объектой системы.

едрить колотить! а мужики лисперы и не знали то!!

anonymous
()
Ответ на: комментарий от anonymous

Ты не прав. В vb адовые массивы. Если учесть, что его в основном в excel использует, получилось особо тонко....

Shadow ★★★★★
()
Ответ на: комментарий от no-such-file

В контексте наличия указателей, просто яйца в профиль.

Shadow ★★★★★
()
Ответ на: комментарий от no-such-file
var j;

for(j = 0; j < 3; j++) {
  console.log('j1 %s', j)
  for(j = 0; j < 3; j++) {
    console.log('j2 %s', j)
  }
}

И уже как бы становится очевидно, что j одна и та же? Тогда в чём смысл нытья?

Ты прикидываешься? Если да, то получается очень хорошо, молодец. Ещё раз отвечаю: к такому коду претензий нет. Претензия есть вот к такому

for(var j = 0; j < 3; j++) {
  console.log('j1 %s', j)
  for(var j = 0; j < 3; j++) {
    console.log('j2 %s', j)
  }
}
И она в том что это поведение неочевидно. И хватит уже заливать про дизайн соотвествующий начальному ТЗ. Неудачное ТЗ и из него следует неудачный язык. Я с этим не спорю.

AndreyKl ★★★★★
() автор топика
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от int64

Глобальная - это видимая отовсюду. Из любого места. В JS нет такого.

любопытно,

var i = 25

function f1() {
  function f2() {
    ..
    function fn() {
       alert(i)
    }
  }
}


неужто не 25 покажет алерт (при условии что нигде не было var) ?

Если да - то вообще не понятно чем твоё понятие «глобальная» отличается от «внешняя». И где (кроме php) есть ещё из популярных языков такое понятие «глобальная» о котором ты говоришь?

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от int64

Так твое мнение и отношение к чем-либо это твой удел. Сиди страдай. Разве если бы ты не страдал, ходил бы жаловаться по форумам о чем-то?

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

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от int64

я вот не пойму сейчас..

ты про {globalVar: 1} и хвастаешься что его видно в эвале, после того как ты его туда передал, а, скажем, util не видно (я кстати не уверен)? ну круто, чё. больше вопросов нет.

AndreyKl ★★★★★
() автор топика
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от crutch_master

Тебе ответить на вопрос есть что?

есть: у тебя дурацкие требования.

То есть ты язык не изучил, но виноват не ты.

То что я знаю как работает var не делает его ни на грамм лучше.

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от int64

На самом деле есть, но не унифицированно. В браузере window, у воркера self, у ноды global. Если ты на верхнем уровне что-то объявишь, оно зашпилится к глобальному контексту.

Vit ★★★★★
()
Ответ на: комментарий от AndreyKl

Ещё раз отвечаю: к такому коду претензий нет. Претензия есть вот к такому

Это ты прикидываешься

if (...) { let a = 1; } else { let a = 2; }
не работает и let не является заменой var. Почему ради let ты допускаешь изменение кода, а ради var нет? УПРЛС?

no-such-file ★★★★★
()
Ответ на: комментарий от Vit

В ноде есть vm/script.runInContext(customObject), где если ты что-то объявишь на верзнем уровне, оно зашпилится как проперти у customObject. И один и тот же скрипт можно выполнять в контекстах разных «глобальных» глобальных объектов.

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

anonymous
()
Ответ на: комментарий от AndreyKl

Если вам очень хочется, то глобальный объект в js это null, который расширяется Object.prototype, который расширяется цепоякой других прототипов. Например в браузере до объекта window, но это может быть любой кастомный объект, какой угодно, который расширяется объектами scope, каждый из которых расширяется вложенными скоупами.

именно поэтому, например, у вас в любой области видимости есть такая «перемеменная» которая на самом деле свойство Object.prototype, как hasOwnProperty, или propertyIsEnumerable, если у вас объект который в данный момент выставлен глобальным контекстом, не Object.create(null).

int64
()
Ответ на: комментарий от anonymous

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

Vit ★★★★★
()
Ответ на: комментарий от Vit

Лолчто. Модули это тоже, например, разные экземпляры скриптов. Что тебе мешает построить модульную систему, в которой у каждого модуля «глобальный» контекст будет свой собственный. И у каждого модуля будет свой собственный global, который может быть реализован например Proxy объектом, с какой-нибудь хитрой логикой, с разграничением прав.

Предмет обсуждения был о том, что в js нет глобальной области видимости. Есть глобальные объекты. И их можно перегружать.

anonymous
()
Ответ на: комментарий от anonymous

Что тебе мешает построить модульную систему, в которой у каждого модуля «глобальный» контекст будет свой собственный

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

Т.е.

function f() {
    window.v = 42;
}
В браузере создаст переменную в глобальном скоупе. Но на самом деле даже window указывать не надо, т.к. js вообще использует глобальный скоуп по-умолчанию, если переменная не объявлена локальной.

Поэтому в js глобальные переменные, это отдельный вид переменных, а не просто «локальные» переменные в глобальном скоупе (каким бы он ни был).

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от no-such-file

Нет. Ты не прав. Если перегружен глобальный контекст. То твоя window.v не будет доступна в соседнем скрипте. Понимаешь? Поэтому она не глобальна.

anonymous
()
Ответ на: комментарий от Vit

ВИДИМАЯ ОТОВСЮДУ

Если у тебя для каждого скрипта отдельный глобальный контекст, то как ты объявишь ГЛОБАЛЬНУЮ переменную, которая будет видна во всех скриптах в рамках процесса??

anonymous
()
Ответ на: комментарий от no-such-file

Поэтому в js глобальные переменные

Нет в js Такого понятия. То, что вы под ним подразумеваете, на самом деле свойства объекта который выставлен глобальным контекстом для текущего скрипта.

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

И твоя window.v объявленная в модуле a.js в модуле b.js будет доступна никак window.v, а как window.modules.a.v

anonymous
()
Ответ на: комментарий от anonymous

То твоя window.v не будет доступна в соседнем скрипте

А мне и наплевать на соседний скрипт. Глобальность не означает, что переменную должно быть видно вообще везде во вселенной. Её видно из соседней функции. Этого достаточно.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

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

Vit ★★★★★
()
Ответ на: комментарий от no-such-file

Это уже не глобальность, а локальность.

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

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

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

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

anonymous
()
Ответ на: комментарий от Vit

Я и в рамках одного скрипта, могу вызвать function.toString().runInContext(customContext) И все обращения в этой функции к импортируемым переменным будут импортироваться из моего кастомного объекта.

anonymous
()
Ответ на: комментарий от anonymous

Нет в js Такого понятия

Есть в js такое понятие, как и в большинстве других языков.

на самом деле свойства объекта который выставлен глобальным контекстом для текущего скрипта

Это часть реализации того, что называется глобальными переменными. Тем не менее всё равно для разграничения доступа используется специальный синтаксис, тот самый var. Иначе переменные этого «глобального объекта» были бы в функциях недоступны. Т.е. само по себе выставление какого-то объекта, как контекста для функции, недостаточно.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от anonymous

Можешь. И процесс форкнуть можешь тоже. Но по дефолту всё пускается в одном и том же контексте, со всеми вытекающими последствиями. Речь о простом запуске, а не о виртуальных машинах, воркерах и разных процессах.

Vit ★★★★★
()
Ответ на: комментарий от anonymous

Опасность глобальных переменных, как раз в том, что их может перегрузить какой-то сторонний скрипт

Нет, «опасность» не в этом, а в том, что они добавляют «состояние» для программы. Т.е. твоя функция может вести себя по-разному в зависимости от глобальных переменных и два вызова foo() и foo() могут работать по-разному. Это затрудняет отладку и «аргументацию» при разборе работы программы, особенно если есть взаимные зависимости между вызовами функций и изменением состояния. В таких случаях нужно не просто видеть код, чтобы понять как он работает, а прослеживать разные варианты вызовов - что за чем вызывается, в какой последовательности и т.п. (делать трассировку в уме). Получается такой себе лапше-goto на стеройдах.

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

Нет, только из одного специального скоупа. И нужно это для того чтобы передавать в функции какие-то глобальные ресурсы (типа window). Иначе пришлось бы в каждую функцию пихать объекты «верхнего» скоупа как параметры.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Почему ради let ты допускаешь изменение кода, а ради var нет? УПРЛС?

Потому что, как я уже указал, поведение var - весьма неочевидно.

AndreyKl ★★★★★
() автор топика
Ответ на: комментарий от AndreyKl

поведение var - весьма неочевидно

Если использовать как let, т.е. писать все var в начале функции, то всё очевидно.

Кстати, что касается for(let i=... то его применение ограничено. Если нам нужно получить значение i после цикла, то внезапно начинаются не очевидные проблемы.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

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

Ага, она глобальна для нижестоящих скопов. И если у тебя нет гарантий иммутабельности, то считай это миной ограниченного поражения.

anonymous
()
Ответ на: комментарий от AndreyKl

поведение var - весьма неочевидно

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

anonymous
()
Ответ на: комментарий от no-such-file

Если использовать как let, т.е. писать все var в начале функции, то всё очевидно.

ничего подобного, лет, в отличие от вар, можно использовать вначале блока https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
Поэтому странных проблем не возникает

Кстати, что касается for(let i=... то его применение ограничено. Если нам нужно получить значение i после цикла, то внезапно начинаются не очевидные проблемы.

1) Область видимости лет - блок.
2) При повторном объявлении внутри одного и того же блока получаем синтаксическую ошибку.

Если сравнивать с вар, то у вар как то так:
1) область видимости - функция.
2) при повторном объявлении используем уже объявленную переменную

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

Так или иначе правила лет проще и очевиднее, плюс какой-никакой контроль за самоочевидными ошибками-опечатками.

AndreyKl ★★★★★
() автор топика
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

ничего подобного, лет, в отличие от вар, можно использовать вначале блока

Да, но если ты собрался выкинуть var и оставить let, то это «в начале блока» и будет в начале функции. Тогда в чём разница? Размещай var в начале функции.

Область видимости лет - блок

Для for(let это будет блок цикла. Такую переменную нельзя использовать после цикла и это ни разу не очевидно. Иначе об этом не спрашивали бы постоянно.

for(let i = 0; i < 3; i++) {
  for(let j = 0; j < 3; j++) {
     if (j > Math.random()*2) break;
  }
  console.log('%s %s', i, j)
}

не работает. Внезапно да?

не ругаться на повторно объявленные переменные

Они не «повторно объявленные». Какой же ты дуб. Фича не в том что можно писать var несколько раз, а блджад в том, что можно _не писать_ var каждый раз. ИМХО let вообще не нужен, т.к. только создаёт путаницу, не давая ничего нового.

no-such-file ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.