Рубрики
Без рубрики

Легко вступление в лексику в JavaScript

Михаил Макмиллан Легко вступление к лексическому охвату в JavaScriptPhoto по храмому Cerulelan на Unsplashlexlical Scoping – это тема, которая пугает многих программистов. Одним из лучших объяснений лексической области можно найти в книге Кайла Симпсона, которую вы не знаете JS: область и закрытие. Однако даже

Автор оригинала: FreeCodeCamp Community Member.

Михаил Макмиллан

Лексическая область – это тема, которая пугает многих программистов. Одно из лучших объяснений лексической области можно найти в книге Кайла Симпсона Вы не знаете JS: Область и закрытия Отказ Однако даже его объяснение не хватает, потому что он не использует реальный пример.

Один из лучших реальных примеров того, как работает лексические океины, и почему важно, можно найти в знаменитом учебном книге «Структуру и интерпретацию компьютерных программ» (SICP) Harold Abelson и Gerald Jay Sussman. Вот ссылка на PDF версию книги: SiCP Отказ

SICP использует схему, диалект Lisp и считается одним из лучших текстов вводных компьютерных наук, когда-либо написанных. В этой статье я хотел бы пересматривать свой пример лексической области, используя JavaScript в качестве языка программирования.

Наш пример

Примером примера Abelson и Sussman используют вычислительные квадратные корни с использованием метода Ньютона. Метод Ньютона работает путем определения последовательных приближений для квадратного корня числа до тех пор, пока приближение не поступило в пределах допустимого доступа. Давайте поработаем в примере, как в SICP Abelson и Sussman.

Пример, который они используют, находит квадратный корень из 2. Вы начинаете, делая предположение на квадратный корень из 2, скажем, 1. Вы улучшаете это предположение, разделив первоначальный номер по угаданию, а затем усреднение того, что Qualient и текущий угадают, чтобы придумать следующую предположение. Вы остановитесь, когда вы достигаете приемлемого уровня приближения. Abelson и Sussman используют значение 0,001. Здесь проходит через первые несколько шагов в расчете:

Square root to find: 2First guess: 1Quotient: 2 / 1 = 2Average: (2+1) / 2 = 1.5Next guess: 1.5Quotient: 1.5 / 2 = 1.3333Average: (1.3333 + 1.5) / 2 = 1.4167Next guess: 1.4167Quotient: 1.4167 / 2 = 1.4118Average: (1.4167 + 1.4118) / 2 = 1.4142

И так до тех пор, пока догадка не наступает в нашему пределу приближения, который для этого алгоритма составляет 0,001.

Функция JavaScript для метода Ньютона

После этой демонстрации метода авторы описывают общую процедуру для решения этой проблемы в схеме. Вместо того, чтобы показать вам код схемы, я напишу это в JavaScript:

function sqrt_iter(guess, x) {  if (isGoodEnough(guess, x)) {    return guess;  }    else {    return sqrt_iter(improve(guess, x), x);  }}

Далее нам нужно много других функций, включая Isgoodenough () и улучшить () вместе с некоторыми другими функциями помощника. Мы начнем с улучшения (). Вот определение:

function improve(guess, x) {  return average(guess, (x / guess));}

Эта функция использует среднюю функцию помощника (). Вот что определение:

function average(x, y) {  return (x+y) / 2;}

Теперь мы готовы определить функцию isGoodenough (). Эта функция служит для определения, когда наше предположение достаточно близко к нашему приближению допуска (0,001). Вот определение isGoodenough ():

function isGoodEnough(guess, x) {  return (Math.abs(square(guess) - x)) < 0.001;}

Эта функция использует функцию квадрата (), которая легко определить:

function square(x) {  return x * x;}

Теперь все, что нам нужно, это функция, чтобы все началось:

function sqrt(x) {  return sqrt_iter(1.0, x);}

Эта функция использует 1.0 в качестве начала предположения, что обычно просто отлично.

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

> .load sqrt_iter.js> sqrt(3)1.7321428571428572> sqrt(9)3.00009155413138> sqrt(94 + 87)13.453624188555612> sqrt(144)12.000000012408687

Функции, кажется, работают хорошо. Тем не менее, здесь есть лучшая идея скрывается здесь. Эти функции все написаны независимо, даже если они предназначены для работы в сочетании друг с другом. Мы, вероятно, не собираемся использовать функцию isGoodenough () с любым другим набором функций или самостоятельно. Кроме того, единственная функция, которая имеет значение для пользователя, является функцией SQRT (), поскольку это тот, который вызывается, чтобы найти квадратный корень.

Блок Scoping скрывает функции помощника

Раствор здесь состоит в том, чтобы использовать блок Scoping для определения всех необходимых функций помощника в блоке функции SQRT (). Мы собираемся удалить квадрат () и среднее () из определения, поскольку эти функции могут быть полезны в других определениях функций и не так ограничены использованием в алгоритме, который реализует метод Ньютона. Вот определение функции SQRT () сейчас с другими функциями помощника, определенной в пределах объема SQRT ():

function sqrt(x) {  function improve(guess, x) {    return average(guess, (x / guess));  }  function isGoodEnough(guess, x) {    return (Math.abs(square(guess) - x)) > 0.001;  }  function sqrt_iter(guess, x) {    if (isGoodEnough(guess, x)) {      return guess;    }    else {      return sqrt_iter(improve(guess, x), x);    }  }  return sqrt_iter(1.0, x);}

Теперь мы можем загрузить эту программу в нашу оболочку и вычислить некоторые квадратные корни:

> .load sqrt_iter.js> sqrt(9)3.00009155413138> sqrt(2)1.4142156862745097> sqrt(3.14159)1.772581833543688> sqrt(144)12.000000012408687

Обратите внимание, что вы не можете позвонить ни одному из функций Helper снаружи функции SQRT ():

> sqrt(9)3.00009155413138> sqrt(2)1.4142156862745097> improve(1,2)ReferenceError: improve is not defined> isGoodEnough(1.414, 2)ReferenceError: isGoodEnough is not defined

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

Мы сильно улучшили нашу реализацию метода Ньютона, но есть еще одна вещь, которую мы можем сделать, чтобы улучшить нашу функцию SQRT (), упрощая ее еще больше, используя преимущества лексической области.

Улучшение ясности с лексическим объемом

Концепция лексической области состоит в том, что когда переменная связана с окружающей средой, другие процедуры (функции), которые определены в этой среде, имеют доступ к значению этой переменной. Это означает, что в функции SQRT () параметр x привязан к этой функции, что означает, что любая другая функция, определенная в корпусе SQRT (), может получить доступ к x.

Зная это, мы можем упростить определение SQRT () еще больше, удалив все ссылки на X в определениях функций, поскольку X теперь X представляет собой бесплатную переменную и доступную всеми из них. Вот наше новое определение SQRT ():

function sqrt(x) {  function isGoodEnough(guess) {    return (Math.abs(square(guess) - x)) > 0.001;  }  function improve(guess) {    return average(guess, (x / guess));  }  function sqrt_iter(guess) {    if (isGoodEnough(guess)) {      return guess;    }    else {      return sqrt_iter(improve(guess));    }  }  return sqrt_iter(1.0);}

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

> .load sqrt_iter.js> sqrt(9)3.00009155413138> sqrt(2)1.4142156862745097> sqrt(123+37)12.649110680047308> sqrt(144)12.000000012408687

Лексическая структура Scoping и Block являются важными особенностями JavaScript и позволяют нам построить программы, которые легче понимать и управлять и управлять. Это особенно важно, когда мы начинаем строить большие, более сложные программы.

Оригинал: “https://www.freecodecamp.org/news/lexical-scoping-in-javascript-e876cd221b74/”