Разница между объявлением функции и выражением функции для моего случая - PullRequest
0 голосов
/ 14 ноября 2018

Кто-то, пожалуйста, объясните, что здесь происходит.

 var y = 1;
 if (function f(){return 'some text';}) {
     y += typeof f;
 }
 console.log(y);// "1undefined"

если я изменю его на выражение функции

 var y = 1;
 if (a = function f(){return 'some text';}) {
     y += typeof a;
 }
 console.log(y);// "1function"

Ответы [ 4 ]

0 голосов
/ 09 декабря 2018

Посмотрите на эти примеры:

// function declaration
function A() { return 'AAAA'; }
console.log('A: ', typeof A); // A: function

// mixing function declaration and expression - wrong way 
b = function B() { return 'BBBB'; };
console.log('b: ', typeof b); // b: function
console.log('B: ', typeof B); // B: undefined
// Why?
// 'B' is declared inside an expression and 'dies' after the expression
// ends, i.e. after b get assigned the right side of '='
// 'b', on the other side, got the function assigned and lives
// further on the scope.

// function declaration - right way
b2 = function() { return 'BBBB'; };
console.log('b2: ', typeof b2); // b2: function

// declaring the function inside the 'if' expression... same as with B
if(function C() { return 'C';}) {
	console.log('C (in): ', typeof C); // undefined
}
console.log('C: (out)', typeof C); // undefined
// ... it's the same as in here:
x = (function D() { return 'D';});
console.log('x: ', typeof x); // function
console.log('D: ', typeof D); // undefined

// assigning a variable (same as with 'B' example)
if(z = function Z() { return 'Z'; }) {
	console.log('z: ', typeof z); // function
  console.log('Z: ', typeof Z); // undefined
}
// ... and the same as with Z
y = (z2 = function Z2() { return 'Z2'; });
console.log('y: ', typeof y); // function
console.log('z2: ', typeof z2); // function
console.log('Z2: ', typeof Z2); // undefined
0 голосов
/ 14 ноября 2018

Объявление функции создает переменную с тем же именем в текущей области.

function a() {
    function b() {
    }
}

В вышеприведенном примере переменная b создается в области действия a.


Выражение функции создает переменную с тем же именем в собственной области видимости.

function a() {
    (function b() {
    })
}

В приведенном выше примере переменная b создается в области действия b, ноnot a.


В вашем первом примере (выражение именованной функции ), f не существует вне функции, поэтому это undefined.

Во втором примере (также именованная функция express ) вы явно присваиваете функции a (неявный глобал), чтобы она была определена.

Ни один изВ ваших примерах есть объявление функции, несмотря на заголовок вашего вопроса.Помещение ключевого слова function в условие if () делает его таким же выражением, как и на RHS =.

0 голосов
/ 14 ноября 2018

Разница в том, что в первом примере в качестве условного выражения оператора if указано функциональное выражение . Выражения функций не создают именованную сущность во вложенной области видимости, согласно ECMA-262 [2015] §14.1.20 ( полужирный выделение):

ПРИМЕЧАНИЕ 2

На BindingIdentifier в FunctionExpression можно ссылаться из FunctionExpression FunctionBody , чтобы позволить функции вызывать себя рекурсивно , Тем не менее; в отличие от FunctionDeclaration , BindingIdentifier в FunctionExpression не может ссылаться из и не влияет на область действия, охватывающую FunctionExpression .

Причина, по которой он интерпретируется как FunctionExpression , а не FunctionDeclaration , заключается в том, что он задан как условное выражение оператора if, как определено в ECMA -262 [2015] §13.6.7 :

Семантика времени выполнения: оценка

IfStatement : if ( Выражение ) Выписка else Заявление

Ваш второй пример работает, потому что условное выражение if является выражением присваивания, вычисление которого присваивает результат function expression (т. Е. Объект функции) переменной a, которая уже была объявлена ​​в объем ограждения.

Ссылки, приведенные здесь, относятся к ECMAScript 2015, но почти идентичные положения приведены в более ранних версиях спецификации.

0 голосов
/ 14 ноября 2018

Условие оператора if всегда является выражением. Во втором случае это выражение assignemnt, которое устанавливает глобальную (!) Переменную a для функции, в первом случае это просто выражение функции, и функция уходит в никуда (она нигде не сохраняется). f - это просто имя функции внутри самой функции (для рекурсии). Поэтому f не определено вне его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...