Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Почему не следует использовать var в global (https://javascript.ru/forum/misc/48268-pochemu-ne-sleduet-ispolzovat-var-v-global.html)

foo 27.06.2014 10:57

Почему не следует использовать var в global
 
Наверное, многие думают, что объявленная в global переменная с var отличается от той что без var только тем, что имеет скрытое св-во dontdelete. Я выяснил, что в node, помимо этого, она не копируется в global. Возможно, еще где-нибудь. Это значит, к примеру, что она не будет доступна через конструкцию for(i in global). Поэтому, в общем случае, не стоит объявлять через вар в глобальной области. Объявляя без вар мы ничего не теряем. Но не наоборот. Так что это тупой базворд, не надо слушать этих умников от CS.

Octane 27.06.2014 11:20

Стоит различать свойства глобального объекта и глобальные переменные.
Почитай, например http://dmitrysoshnikov.com/ecmascrip...riable-object/
Отличие не только в dontdelete

var Object; //глобальная функция
alert(typeof Object); //по прежнему доступен


var postMessage; //свойство объекта window
alert(typeof postMessage) //теперь до postMessage можно достучаться
                         // только с помощью window.postMessage

Erolast 27.06.2014 11:36

В соседней теме на то же тебе же отвечал, процитирую:
Цитата:

Сообщение от Erolast (Сообщение 318204)
Это пережиток былого. В современном javascript при объявлении переменных ВСЕГДА нужно использовать var (ну либо const/let). Попробуй объявить без var в строгом режиме - и интерпретатор радостно выдаст ошибку.
"use strict";

try {
  somevar = 100;
} 
catch (e) {
  alert(e);
}


В node.js область видимости текущего скрипта не равна глобальной области видимости. Каждый модуль создает свою область видимости. Потому объявленная через var переменная не становится глобальной, да.


foo 27.06.2014 11:50

Цитата:

Сообщение от Erolast (Сообщение 318205)
В соседней теме на то же тебе же отвечал, процитирую:

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

foo 27.06.2014 11:58

Цитата:

Сообщение от Octane
по прежнему доступен

А что он из себя представляет? В node он undefined. А у Вас что?

Octane 27.06.2014 12:01

Object undefined?

foo 27.06.2014 12:04

Цитата:

Сообщение от Octane
по прежнему доступен

попробовал в Firefox вот так:
Object=1
console.log(typeof Object)// number

foo 27.06.2014 12:04

Цитата:

Сообщение от Octane (Сообщение 318214)
Object undefined?

Да

foo 27.06.2014 12:08

Цитата:

Сообщение от Octane (Сообщение 318214)
Object undefined?

Да, в firefox и в node, если
var Object=1;
console.log(typeof Object)//number

так, то что с var, что без, number

Erolast 27.06.2014 12:11

Цитата:

Я в соседней теме тебе ответил
Процитирую ту часть моего ответа на твой ответ, что как раз в тему этой темы:
Цитата:

Цитата:

Мне плевать на него [strict mode]
То есть, ты признаешь ранние стандарты, а на современные тебе плевать?) Ну-ну, продолжай в том же духе.

foo 27.06.2014 12:13

Цитата:

Сообщение от Erolast
стандарты

Это не стандарт

Erolast 27.06.2014 14:06

strict mode - режим соответствия современному стандарту.

Sweet 27.06.2014 14:45

Вот пример на ноде:
Есть модуль A:
var func = require("B");

for(i = 0; i < 2; i++) {
  func();
}

И модуль B:
module.exports = function () {
  for(i = 2; i != 0; i--) console.log(i);
};

И вуаля! Вот таким нехитрым способом можно прострелить себе ногу.

foo 27.06.2014 14:50

Цитата:

Сообщение от Erolast
strict mode - режим соответствия современному стандарту.

Опциональный

foo 27.06.2014 14:51

Цитата:

Сообщение от Sweet
И вуаля! Вот таким нехитрым способом можно прострелить себе ногу.

И что?

Erolast 27.06.2014 15:09

Цитата:

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

nverv 27.06.2014 15:44

Цитата:

Сообщение от Erolast (Сообщение 318268)
Желательный. Очень желательный. Существует он лишь для того, чтобы код, написанный по ранним стандартам, работать продолжал.

какова вероятность что "жесткий режим" будет обязательный? и когда

для меня принципиально важно понять надо ли мне отказывать себе в использовании синтаксического сахара упрощенного объявления переменных: х.у.имя1 = х.у.имя2

Erolast 27.06.2014 15:45

Ты путаешь. Это свойства, а не переменные. Свойства, разумеется, объявлять не надо.

Sweet 27.06.2014 15:45

Цитата:

Сообщение от foo
И что?

И что "и что"?

foo 27.06.2014 15:48

Цитата:

Сообщение от Sweet
И что "и что"?

Какое это отношение имеет к тому, что я сказал?

nverv 27.06.2014 15:53

Цитата:

Сообщение от Erolast (Сообщение 318294)
Ты путаешь. Это свойства, а не переменные. Свойства, разумеется, объявлять не надо.

я не путаю

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

ну какой же есть смысл использования var в глобале если тот же самый эфект и даже лучше достигается методом добавьСвойство

Erolast 27.06.2014 15:59

Ты, чтоли, об этом? Ну можно и методом defineProperty(window, value). Можно и через window.value. Технически разницы нету. Но мне почему-то кажется, что так не проще)

kobezzza 27.06.2014 15:59

nverv, чувак, никто тебе не запрещает писать

this.foo = ...


Более того это типичный пример "портируемого" кода для разных окружений, т.к.:

браузер - глобальный объект
поток - глобальный объект
node - exports

***

Плохо когда пишут:

foo =


т.к. такое поведение было убрано из стандарта - хорошо это или плохо другой вопрос, но на мой взгляд они сделали всё правильно, т.к. подход к переменным в JS изначально был неверный и в ECMAScript6 это исправили (добавили let и const).

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

***

В новый стандарт JS добавили нативные модули, и при их использовании var будет добавлять не в global space, а в контекст модуля (как в ноде) и тут уже очевидная разница.

JS эволюционирует, т.к. меняются его задачи и сферы применения, так например появятся типы, структуры, уже появились "настоящие" массивы и возможность ручного управления памятью и ещё куча всего. От того, что кому то кажется сложным мир не изменится и это сугубо твои проблемы. Не хочешь учиться - иди работать в макдональдс.

nverv 27.06.2014 16:04

Цитата:

Сообщение от Erolast (Сообщение 318304)
Ты, чтоли, об этом? Ну можно и методом defineProperty(window, value). Можно и через window.value. Технически разницы нету. Но мне почему-то кажется, что так не проще)

но же "строгий режим" запрещает так писать -
window.value = 1

вопрос- наплевать ли мне на этот запрет и жить удобнее, или с самого начала приучиться использовать defineProperty ?

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

Erolast 27.06.2014 16:05

Цитата:

но же "строгий режим" запрещает так писать -
window.value = 1
С чего бы вдруг? Не запрещает.

kobezzza 27.06.2014 16:06

Цитата:

но же "строгий режим" запрещает так писать -
window.value = 1
Ты путаешь, так писать можно - это нормальное поведение.

Нельзя писать

Цитата:

value = 1

foo 27.06.2014 16:35

Цитата:

Сообщение от kobezzza
Не хочешь учиться - иди работать в макдональдс.

Строго наоборот. Хомячье не понимает программирования, поэтому ему нужен сахар. Инженер превращается в секретаршу с интерфейсом, но зато их теперь много, и можно клепать энтерпрайз.

Erolast 27.06.2014 16:36

Да вот кто б говорил...

nverv 27.06.2014 16:46

Цитата:

Сообщение от kobezzza (Сообщение 318313)
Ты путаешь, так писать можно - это нормальное поведение.

а читая фленагана я понял что нельзя так

"
все переменные должны объявляться... стр 134


или тут речь только о локальных переменных создаваемых var

kobezzza 27.06.2014 16:49

nverv, ты просто не правильно понял, если ты явно пишешь кому ты ставишь свойство - то юзай на здоровье.

Плохо когда юзают такие штуки
a = 2 // неявная декларация global.a = 2

function bar() {
  b = 3 // неявная декларация global.b = 3
}

foo // неявная декларация document.getElementById('foo')

Erolast 27.06.2014 16:50

Цитата:

а читая фленагана я понял что нельзя так

"
все переменные должны объявляться...
Уже говорилось:
Цитата:

Ты путаешь. Это свойства, а не переменные. Свойства, разумеется, объявлять не надо.
Объявляются переменные, но не свойства. Свойства просто определяются.

nverv 27.06.2014 16:52

спасибо товарищи, отпустило

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

foo 27.06.2014 16:53

Цитата:

Сообщение от Erolast
Свойства просто определяются.

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

Erolast 27.06.2014 16:56

Переменные в объекте? Свойства из функций? Что? :blink:

foo 27.06.2014 17:01

Цитата:

Сообщение от Erolast
Переменные в объекте? Свойства из функций? Что?

ну вот так
global.a=1
function getHuy(x){
   return global.a+x
}
getHuy(1)//huy тебе а не global.a

Erolast 27.06.2014 17:31

Даже отвечать на этот бред не хочется.

foo 27.06.2014 17:33

Цитата:

Сообщение от Erolast
не хочется

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

kobezzza 27.06.2014 17:36

Цитата:

Сообщение от Erolast (Сообщение 318359)
Даже отвечать на этот бред не хочется.

Ну на самом деле, в "чисто" функциональных языках такой сценарий есть и сделан он в первую очередь, чтобы 100% гарантировать, что результат функции зависит только от её входных параметров, но для языка общего назначения - это перебор, хотя, если бы был введён новый вид функций для этой фичи, то было бы прикольно.

foo 27.06.2014 17:46

Цитата:

Сообщение от kobezzza
в "чисто" функциональных языках

В чисто функциональных языках другая фича -- иммутабельность. Здесь же идет речь о том, что у замыканий свой неймспейс, у объектов (которые под капотом тоже функции) свой. Глобальный скоп замыканий пересекается с неймспейсом глобального объекта. Так вот, если они считают, что из объекта не следует иметь доступ к глобальному скопу замыканий, логично было бы изолировать и неймспейс объектов от обращения изнутри функций. И получим 2 отдельных языка, которые не пересекаются.

Erolast 27.06.2014 17:48

Опять же
Цитата:

Даже отвечать на этот бред не хочется.


Часовой пояс GMT +3, время: 10:10.