Комментарии 38
Очень неплохая статья, так держать!
Можно было бы еще добавить определение хойстинга/hoisting, т.к. оно также играет важную роль. Так, например, что будет выведено в консоль в след.ситуации:
Под конец Вы стали рассматривать публичные/приватные переменные и как организовать свой код, чтобы добиться определенного результата. Можно было также привести названия паттернов Вы использовали, чтобы было понятно, что это не Вами только что придуманная структура, а известный паттерн и активно используется разработчиками по всему миру.
Также можно было бы упямонуть про ES6 let, которая напрямую затрагивает тему данной статьи.
Можно было бы еще добавить определение хойстинга/hoisting, т.к. оно также играет важную роль. Так, например, что будет выведено в консоль в след.ситуации:
var func = function() { console.log('1'); };
function func() { console.log('2'); }
func();
Под конец Вы стали рассматривать публичные/приватные переменные и как организовать свой код, чтобы добиться определенного результата. Можно было также привести названия паттернов Вы использовали, чтобы было понятно, что это не Вами только что придуманная структура, а известный паттерн и активно используется разработчиками по всему миру.
Также можно было бы упямонуть про ES6 let, которая напрямую затрагивает тему данной статьи.
+6
Перевод же…
+4
В свое время не плохо помогло =) learn.javascript.ru/function-declaration-expression
+1
Хорошая статья для начинающих, но странно, что в конце 2013 года автор совсем не затронул
UPD: Черт, выше уже написали про
let
и его влияние на области видимости.UPD: Черт, выше уже написали про
let
.+3
Рано его еще использовать. В частности v8 еще не умеет оптимизировать функции с let (возможно ситуация изменится с запуском TurboFan). Что влечет в свою очередь примерно x20 кратную потерю производительности, что порой критично. Да и вообще меня не покидает ощущение, что классы и let — это эдакий популизм. В отличии от реально нужных генераторов и ES7 async/await, argument pattern'ов и destructuring assignment (который, к сожалению, в v8 еще не родили, хотя использовать его с генераторами самое оно).
+4
Понравилось, спасибо. Вроде и ничего нового, но зато всё по делу.
Хотя у меня на практике обычно по простому
Хотя у меня на практике обычно по простому
var Module= {
mothod1 : function() {
},
mothod2 : function() {
},
mothod3 : function() {
}
}
0
Отличная статья, но есть неточность: в первом примере — это не всегда так.
В ноде это будет объявлено в глобальной области, однако в браузере — не в глобальной, а внутри области window.
Глобальная область в браузере доступна примерно так: name = 'Todo';
Не могу придумать пример, когда это важно, но раз уж статья об областях видимости…
В ноде это будет объявлено в глобальной области, однако в браузере — не в глобальной, а внутри области window.
Глобальная область в браузере доступна примерно так: name = 'Todo';
var name = 'Todo'; // Локальная ОВ
globalName = 'Todo'; // Глобальная ОВ (покуда без var)
Не могу придумать пример, когда это важно, но раз уж статья об областях видимости…
Неверующим
console.log(this); // > Window
-1
НЛО прилетело и опубликовало эту надпись здесь
В браузере? Будет text:
mySuperVar = 'text';
typeof(window.mySuperVar); //string
window.mySuperVar; //text
console.log(window.mySuperVar); //undefined
// actual result: text
0
НЛО прилетело и опубликовало эту надпись здесь
Я думаю, имеется ввиду, что если это писать в консоли, то вывод будет примерно такой:
Покуда сам метод console.log() ничего не возвращает, то сначала печатается undefined, а потом уже переменная.
var myVar = "text";
console.log(window.myVar);
> undefined
> "text"
Покуда сам метод console.log() ничего не возвращает, то сначала печатается undefined, а потом уже переменная.
0
НЛО прилетело и опубликовало эту надпись здесь
Как раз таки наоборот:
var myVar = "text";
console.log(window.myVar);
> text
> undefined
+1
alert(window.mySuperVar)
выводит text
0
НЛО прилетело и опубликовало эту надпись здесь
Я сначала не понял, о чём вы. Я подумал, что console.log(window.mySuperVar) выводит undefined
на самом деле undefined — это не вывод, а возврат функции console.log
на самом деле undefined — это не вывод, а возврат функции console.log
0
function a() {
console.log(1);
return 2;
}
a();
Вывод:
1
2
здесь уже нет никакого undefined. Здесь 1 — вывод console.log(1), а 2 — возврат функции a
+1
В обеих ситуациях это считается глобальной областью: this в браузере это window, в nodejs — переменная определяемая системой.
0
Этот загадочный js…
Тут подумал — если мы используем iframe, то до него можно достучаться через window.frames[0].variable; Следовательно, в iframe это все-таки будет локальный контекст по сравнению с родительским. Хотя даже без var он наружу не бросает. Хитрый js однако. К слову, в статье про области видимости как раз это можно было и раскрыть.
Тут подумал — если мы используем iframe, то до него можно достучаться через window.frames[0].variable; Следовательно, в iframe это все-таки будет локальный контекст по сравнению с родительским. Хотя даже без var он наружу не бросает. Хитрый js однако. К слову, в статье про области видимости как раз это можно было и раскрыть.
ОФФТОП. (Да, поведу себя как ребенок, но раньше об этом не задумывался)
Тут меня осенил гениальный план, как можно воровать личные данные: делаете на своем сайте iframe на чужой сайт, он там открывается, а мы имеем доступ к нему. Хм, я подумал — слишком простая и очевидная схема, и правда — vk так не открылся. Но не сложно догадаться, что виной этому хедер — X-iframe-options: deny. Полез лазить по интернету. Крупные сайты предусмотрели этот заголовок, но из более мелких (всякие интернет-магазины самописные, а так же всякие самописные бложики) спокойно открываются через iframe почти все. Браузер safari. Хм, печально, товарищи.
-2
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Хм. Это все хорошо. И это логично. Но попробовал у себя на локальном файле через file:// — и, к моему удивлению, сработало. У меня был полный доступ к открывшейся странице. Удивленный, полез воспроизводить это на jsfiddle. Но там не сработало. Странное поведение.
0
Хм. В Safari 8.0 этот файл отрабатывает без проблем, если его открывать как file://. На мой взгляд, это может быть достаточно большой дыркой.
Скрытый текст
<!DOCTYPE html>
<html>
<head>
</head>
<script>
var k = 3;
l = 5;
var load = function()
{
window.frames[0].$('body').click(function() { alert('Алерт'); });
}
</script>
<body>
<iframe onload="load()" src="http://raal100.narod.ru" width='500' height='500'></iframe>
</body></html>
0
вот так надо:
просматривайте, какими свойствами обладает объект, в данном случае объект window.frames[0], и да пребудет с вами сила
И ещё: во фрейме должен быть загружен страница того же домена или поддомена.
если во фрейме загружен поддомен, то в нём должно быть запущена строчка document.domain = "<домен родительского окна>".
window.frames[0].contentWindow.variable
просматривайте, какими свойствами обладает объект, в данном случае объект window.frames[0], и да пребудет с вами сила
И ещё: во фрейме должен быть загружен страница того же домена или поддомена.
если во фрейме загружен поддомен, то в нём должно быть запущена строчка document.domain = "<домен родительского окна>".
0
Каждая ОВ назначает своё значение переменной “this”
Это не совсем верно.
this
это свойство контекста выполнения (execution context), а не области видимости (scope).например,
var b = 1;
function a() {
console.log('scope b:', b);
console.log('this b:', this.b);
// здесь небольшая магия, в es6, если не указано явно, this будет null,
// в es5 - глобальный объект
}
a();
a.call({b:2});
+7
что обозначает ключевое слово this, и как оно относится с ОВ?
Никак. Кроме того, что они используются в одном языке. Автор оригинальной статьи или всё переупрощает, или заблуждается.
Помимо функций, есть ещё один способ манипуляции с ОВ. Вы его знаете, но вам говорили никогда им не пользоваться в продакшне (и в общем-то правильно). Это оператор
with
. Он использует существующий объект в качестве ОВ.Рассмотрим такой код:
(function(){
var that = 42;
with({
"that": "foo",
"this": "bar"
}){
console.log(that);
console.log(this);
}
})();
Первый консоль-лог выведет «foo». Переменная that, конечно, объявлена и равна 42, но это во внешней ОВ. Во внутренней есть своя переменная that, и она затеняет («shadowing») переменную из внешней ОВ. Несмотря на экзотический оператор, поведение вполне привычное.
А вот второй консоль-лог выведет глобальный объект. Во внутренней ОВ есть переменная под именем «this», но она не затенила this. Единственное логичное объяснение — при разрешении значения
this
механизм ОВ не используется. А сам this
— это ключевое слово, а не переменная, и ни в какой области видимости переменных не находится, точно так же, как и ключевые слова null
, true
или false
.Ещё раз уточню, это упрёк автору статьи, а не переводчику. Переводчику только похвала, за хороший перевод.
+8
Поддерживаю. Согласен что this это не переменная. Это ссылка на саму локальную область видимости. Почему нельзя так сказать?
0
Это ссылка на саму локальную область видимости. Почему нельзя так сказать?
да потому что this только по умолчанию указывает на локальную область видимости, и this можно менять вызовами apply, call, bind
0
Да нет же, this вообще не указывает на локальную область видимости. Вот, товарищ m1el даже уже продемонстрировал это.
Видимо, вас сбила с толку фраза «Каждая ОВ назначает своё значение переменной “this”,..»
В оригинале она гласит: «Each scope binds a different value of this,..»
Т.е, «Каждая… своё значение» тут в смысле «каждый раз разное значение».
Видимо, вас сбила с толку фраза «Каждая ОВ назначает своё значение переменной “this”,..»
В оригинале она гласит: «Each scope binds a different value of this,..»
Т.е, «Каждая… своё значение» тут в смысле «каждый раз разное значение».
0
Статья неплохая для начинающих, но не полная, либо автор сам не знает, либо не удосужился написать про то, что значения переменных в функциях при ее выполнении инициализируются сразу же как undefined не зависимо есть ли эти переменные в глобальной области или родительской.
+1
Ох уж эти переводы. Почему обязательно «переводить» название языка как яваскрипт, но при этом писать this, call, return, а не это, вызов, вернуть?
0
(ворчу) Вот начитаются сейчас про scope, наизучают js, а потом начинают писать подобное:
[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
+3
Есть ощущение, что автор не программировал с применением ООП, и инкапсуляцию описывает как чудо света.
Вот так поворот! Если приватные методы нельзя вызывать в публичных, их польза близка к нулю.
Но вообще достаточно неплохая статья, одна из лучших на тему.
Интересный поворот в том, что внутри одной ОВ все функции имеют доступ к любым другим, поэтому из публичных методов мы можем вызывать приватные, которые в глобальной ОВ недоступны
Вот так поворот! Если приватные методы нельзя вызывать в публичных, их польза близка к нулю.
Но вообще достаточно неплохая статья, одна из лучших на тему.
+2
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Всё, что вы хотели знать об областях видимости в JavaScript (но боялись спросить)