先来看一段代码
var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
这段代码的结构 中包含立即执行函数,立即执行函数的声明会提到最前面,也就是实际编译器执行代码的顺序是这样的:
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(); 立即执行函数提升至前面
var name = 'World!';
所以,在第一次打印name时,其实name并没有被赋值,那么name为undefined,所以输出Goodbye Jack。
这个代码示例中涉及到了函数声明提升的知识,需要先了解一下 函数声明、函数表达式、匿名函数。
一. 函数声明:
function fnName () {…};使用function关键字声明一个函数,再指定一个函数名,叫函数声明。
函数声明:function 函数名(){}
函数表达式:function 函数名(){},函数名,可写可不写,有名函数是命名函数表达式,无函数名是匿名函数表达式
长得那么像,怎么判断是函数声明还是函数表达式呢?其实就是看上下文判断的
var a = function aaa(){}、(function aaa(){})、以及在前面加运算符的都是函数表达式,(~、+、-、!……)
函数声明和函数表达式不同之处在于,一、Javascript引擎在解析javascript代码时会‘函数声明提升 当前作用域上的函数声明 而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式,二、函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。
接着来看作用域提升这块需要注意的地方:
变量和函数声明都提前时,变量优先级高于函数,变量声明提前也就是var name ,要注意,是声明提前,而不是var name=" ",如果这里理解不清晰,会出现变量值判断错误,返回值自然错误。
变量和函数声明都提前时,变量优先级高于函数,变量声明提前也就是var name !!!!!!!!!!!!!!!!很重要!!!!!!!