После долгого изучения Javascript мне стыдно, что я до сих пор не обобщил весь объем.Сегодня я подытожу его:
Вовлеченный контент:
- глобальная область
- объем функции
- область действия блока
- лексический охват
- Динамическая область видимости Динамическая область видимости связана с механизмом этой ссылки.
Глобальный охват:
Область действия относится к сроку жизни переменной (область, в которой переменная содержит определенное значение).
Глобальная переменная:
Жизненный цикл будет существовать в рамках всей программы.
Доступ к ним может получить любая функция или метод в программе.
По умолчанию он модифицируется в JavaScript.
Глобальные переменные хоть и просты в использовании, но очень пугают, что признают все программисты.
Явно объявить:
объявление с ключевым словом var;
<script type="text/javascript">
var testValue = 123;
var testFunc = function () { console.log('just test') };
/**---------全局变量会挂载到 window 对象上------------**/
console.log(window.testFunc) // ƒ () { console.log('just test') }
console.log(window.testValue) // 123
</script>
На самом деле, если функция, которую мы пишем, не инкапсулирована, она тоже будет глобальной переменной, а ее жизненный цикл — это глобальная область видимости;
Неявное объявление:
безобъявить ключевые словапеременная, JS по умолчанию объявит для вас глобальную переменную! ! !
<script type="text/javascript">
function foo(value) {
result = value + 1; // 没有用 var 修饰
return result;
};
foo(123); // 124
console.log(window.result); // 124 <= 挂在了 window全局对象上
</script>
Теперь переменнаяresultмонтируется наwindowОбъект включен! ! !
Объем функций:
Область действия функции закрыта для внешнего мира, а область внутри функции не может быть напрямую доступна из внешней области! ! !
function bar() {
var testValue = 'inner';
}
console.log(testValue); // 报错:ReferenceError: testValue is not defined
Используйте return для доступа к переменным внутри функций:
function bar(value) {
var testValue = 'inner';
return testValue + value;
}
console.log(bar('fun')); // "innerfun"
Функция похожа на фабрику, мы что-то вводим, она обрабатывает это внутри, а затем дает нам обработанный продукт;
Доступ к переменным внутри функций через замыкания:
function bar(value) {
var testValue = 'inner';
var rusult = testValue + value;
function innser() {
return rusult;
};
return innser();
}
console.log(bar('fun')); // "innerfun"
Что касается замыканий, я не буду слишком много описывать в этой статье, потому что, если вы хотите описать замыкания, вам понадобится такая же длина, как и эта статья;
Немедленно выполнить функцию:
Это очень полезная функция, многие библиотеки используют ее для разделения глобальной области видимости и формирования отдельной области видимости функции;
<script type="text/javascript">
(function() {
var testValue = 123;
var testFunc = function () { console.log('just test'); };
})();
console.log(window.testValue); // undefined
console.log(window.testFunc); // undefined
</script>
он может выполняться автоматически(function() { //... })()Содержимое пакета вполне может устранить влияние глобальных переменных;
Объем блока:
До ES6 не существовало понятия области действия блока. Если у вас есть опыт работы с C++ или Java, вы, вероятно, знакомы с областью видимости на уровне блоков;
for(var i = 0; i < 5; i++) {
// ...
}
console.log(i) // 5
Очевидно, что переменные, объявленные с ключевым словом var, вforПосле того, как цикл все еще сохраняется в этой области;
Это может иллюстрировать:for() { }Тем не менее в глобальной области видимости он не производит такого же эффекта закрытия, как область действия функции;
Если вы хотите достичьобласть действия блокаЗатем нам нужно использоватьletДекларация ключевого слова! ! !
for(let i = 0; i < 5; i++) {
// ...
}
console.log(i) // 报错:ReferenceError: i is not defined
существуетforПосле того, как цикл завершает выполнение, переменная i освобождается, ее больше нет! ! !
Существуют также области блочного уровня, которые могут быть сформированыconstКлючевые слова:
if (true) {
const a = 'inner';
}
console.log(a); // 报错:ReferenceError: a is not defined
letиconstключевое слово, условием для создания области на уровне блока является наличие{ }пакет:
{
let a = 'inner';
}
if (true) {
let b = 'inner';
}
var i = 0;
// ......
Не стоит недооценивать область действия на уровне блоков, она может многое сделать для вас, например:
Вот пример, распространенный в интервью:
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // 5 5 5 5 5
}, 200);
};
Это почти обязательный вопрос для объема, и вы могли бы подумать, что такой результат странный, но это произошло;
I здесь находится в глобальной области видимости, и есть только одно значение.Когда функция обратного вызова выполняется, я, захваченный лексической областью видимости, может быть только 5;
Поскольку этот цикл оценивается как 5 до завершения обратного вызова, как нам вернуть его в нормальное состояние? ? ?
Решение 1: вызовите функцию, создайте область действия функции:
for(var i = 0; i < 5; i++) {
abc(i);
};
function abc(i) {
setTimeout(function() {
console.log(i); // 0 1 2 3 4
}, 200);
}
Это эквивалентно созданию 5 функциональных областей для сохранения, нашего значения i;
Решение 2. Используйте функцию немедленного выполнения для создания области действия функции;
for(var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
}, 200);
})(i);
};
Принцип тот же, что и выше, за исключением того, что функция выполняется автоматически, а значение i сохраняется 5 раз;
Решение 3:letСоздать область блока
for(let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 200);
};
Лексическая область:
Лексическая область видимости относится к видимости переменной и аналоговому значению ее текстового представления («Функциональное программирование JavaScript»);
Звучит очень неясно, но это очень легко понять при анализе кода;
testValue = 'outer';
function afun() {
var testValue = 'middle';
console.log(testValue); // "middle"
function innerFun() {
var testValue = 'inner';
console.log(testValue); // "inner"
}
return innerFun();
}
afun();
console.log(testValue); // "outer"
Когда мы хотим использовать объявленную переменную: JS-движок всегда будет искать внешний домен из ближайшего домена;
Вот еще один практический пример:
var testValue = 'outer';
function foo() {
console.log(testValue); // "outer"
}
function bar() {
var testValue = 'inner';
foo();
}
bar();
Очевидно, когда JS-движок ищет эту переменную, он обнаруживает, что глобальная testValue ближе, что прямо противоположно динамической области видимости;
Как показано на рисунке выше, ниже описывается динамическая область видимости, противоположная лексической области видимости;
Динамический охват:
Одной из самых недооцененных и злоупотребляемых концепций в программировании является динамическая область действия ("Функциональное программирование JavaScript").
Единственное оставшееся место для применения динамической области видимости в JavaScript:thisцитаты, так что это большая дыра! ! ! ! !
Динамическая область, область действия основана на стеке вызовов, а не области, вложенной в код;
Вложенность области видимости имеет те же характеристики, что и лексическая область видимости.При поиске переменных всегда ищите ближайшую область видимости;
То же самое, лексическая область, пример 2, тот же код,еслиявляется динамической областью:
var testValue = 'outer';
function foo() {
console.log(testValue); // "inner"
}
function bar() {
var testValue = 'inner';
foo();
}
bar();
Конечно,JavaScriptКромеthisКроме того, все остальное ищется по лексическому объему! ! !
Зачем понимать динамическую область видимости? Потому что это заставит вас учиться лучшеthisЦитировать! ! !
Ссылки и благодарности:
- «JavaScript, которого вы не знаете»
- Функциональное программирование JavaScript
Прежде всего, благодаря авторам этих двух книг, я также могу хорошо обобщить объем своих собственных примеров и понимания;