show1
выдает ошибку, потому что переменные, объявленные с let
или const
, не могут иметь других переменных с таким же именем , инициализированных в этом блоке (будь то в списке аргументов или с const
/ let
/ var
).
Переменные, на которые ссылаются параметры по умолчанию, имеют нечетные правила области видимости. Каждый аргумент по существу создает другой блок, в котором может быть определено это имя аргумента. Так что
const show3 = function(x, y = () => { x = 2; return x; }) {
в некоторой степени похоже (простите псевдо-код):
const show3 = < function >{
let x = firstArg;
{
let y = secondArg === undefined ? () => { x = 2; return x; } : secondArg;
{
// function body
Когда вы просто назначаете имени переменной в списке аргументов, этот аргумент будет перезаписан. Но когда вы используете синтаксис для инициализации новой переменной (с var
), вы создаете другую привязку для этого имени переменной, которая видна только внутри тела функции:
const show3 = {
let x = firstArg;
{
let y = secondArg === undefined ? () => { x = 2; return x; }
// the x referenced in the above line references the outer x, the first argument
{
// function body
// since "var x" is declared here, any references to "x" in this block
// will only reference the inner x
// but not the outer x
var x = /* something */
Итак, ваш show2
переназначает параметр с именем x
на 3 в первой строке тела функции. Напротив, show3
создает привязку переменной new с тем же именем x
, а ссылка функции y
на x
ссылается на аргумент x
, который отличается.