引申一下,function. 还记得上面提到的预解析,在javascript的预解析中,除了对var 变量的预定义,还包括了提取对函数的定义,所以可以在script的任何地方定义函数,在任何地方调用。不限于它之前.
但函数的定义方式,包括了一种叫字面量定义法, 用var的方法声明function.看下面
alert(typeof y3); //结果?
var y3 = function (){ console.log(\'1\'); }
还记得这个约定吧:调用必须出现在声明之后,为什么呢,如果理解了上面,其实这里答案已经明了。javascript 引擎在预解析 var 时 会给他们一个初始值 undefined,这样一来,如果我们在它的声明之前调用它,javascript 引擎还没拿到它的真实值,自然会报"xxx is not a function" 的错.这也理清了为什么同为函数声明,一个却关系到声明和调用的顺序,一个却无这样的约束。
结论
它是函数,是js执行,动态修改的结果,依然遵循了变量的预解析规则(在上面alert的时候,它还并没有拿到字面量函数的信息)。
如果是两个混合呢。看下面, 同时存在了为y4的变量和function。
alert(typeof y4); //结果?
function y4(){
console.log(\'y4\')
}
var y4;
因为 javascript 在预解析时function的声明优先级高的缘故,所以y4自然为function类型, 但是在当y4 赋值之后(此时js引擎处于执行过程中),它对js的赋值操作将会覆盖function的声明。所以:
alert(typeof y5);
var y5 = \'angle\';
function y5(){
console.log(\'ghost\');
}
alert(y5);
第一次alert结果,因为它处于js 执行过程中的顶端,所以为 function。 第二次再alert时, 它的值已经被重写为5(不要被function的定义位置在下所迷惑。)
从js的解析和执行分开来想,才发现眼前豁然开朗,很多问题的答案都很自然得浮出水面,正如那篇文章作者所说,
> "一旦理解了执行环境、调用对象、闭包、词法作用域、作用域链这些概念,JS语言的很多现象都能迎刃而解。"