2014-01-15 6 views
7

Независимо от того, определяют ли я функцию после переменнойПочему объявления переменных всегда переписывают объявления функций?

var a = 1; 
function a() {}; 
typeof a // number 

Или, если я определить функцию перед переменной

function a() {}; 
var a = 1; 
typeof a // number 

конечный typeof результат всегда number

я нашел объяснение около execution context в http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/

Before executing the function code, create the execution context. 
...... 
Scan the context for variable declarations: 
If the variable name already exists in the variable object, do nothing and continue scanning. 

но это не работает.

Так как я могу это объяснить?

+2

Попробуйте 'var a = function() {};' и посмотрите, что возвращает 'typeof'. – asawyer

+0

[Javascript parse/evaluation order?] (Http://stackoverflow.com/questions/2742195/javascript-parse-evaluation-order) – Andreas

+1

Функция a() {} будет (должна) всегда подниматься до var в области. поэтому последний тип a всегда является числом. Поэтому в «современном» javascript лучше объявить именованные функции как var a = function() {} – mpm

ответ

5

Это связано с JavaScript variable hoisting. Попробуйте вместо этого:

var a = 1; 
var a = function() {}; 
typeof a // function 
1

Вы неявно объявить переменную несколько раз с помощью функции о «функции а() {};», которые, как отмечалось другими тали переменной и неожиданно ведет себя из-за того, что браузер регистрирует объявления.

За кулисами этот оператор создает экземпляр объекта функции и присваивает результат переменной, переданной как имя функции (reference), но это делается до того, как выполняются явные объявления var, и таким образом переопределяет неявное объявление. Если вы просто сделать следующее, он будет работать более интуитивно:

var a = 1; 
a = function(){}; 
console.log(typeof a); // function 

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

Чтобы конкретно ответить на «почему» на этот вопрос: это так, что вы можете использовать эти виды отчетности, чтобы определить функции и использовать их в своих откровенных заявлений, как в

var a = someFunction(); 
function someFunction(){ return 'someVal'; } 

Если операторы функции weren Сначала мы разобрали и подняли, это было невозможно.

0

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

Так что, если вы пишете это:

var a = 1; 
function a() { 
} 

он будет переведен на:

var a; 
function a() { 
} 
a = 1; 

и если вы пишете это:

function a() { 
} 
var a = 1; 

он будет переведен на:

function a() { 
} 
var a; 
a = 1; 

Так что независимо от того, что вы делаете, a = 1; останется на самом дне.

Обратите внимание, что вышеуказанные «переводы» следует рассматривать теоретически. Вероятно, JavaScript имеет способ опустить оператор var a;, если уже есть объявление функции с тем же именем. И также может быть определенный порядок (функции поднимаются до переменных или наоборот). Но все это не влияет на результат инициализации переменной, являющейся единственной частью, которая НЕ поднята вообще.

Смежные вопросы