您的位置:首页 > Web前端 > JavaScript

JS 变量和函数的声明提升

2018-01-22 15:21 477 查看

变量声明提示

以下代码 A 相当于代码 B,

A:

var scope = 'global';
function f(){
console.log(scope);
var scope = 'local';
console.log(scope);
}


B:

var scope = 'global';
function f(){
var scope; // 变量提升到函数顶部
console.log(scope);
scope = 'local'; // 赋值仍停留在原地
console.log(scope);
}


这个函数输出的是:

undefined
local


JavaScript 在函数内声明的所有变量在函数体内始终有定义,因此变量在声明前即可用,也就是说函数内所有的声明(只是声明,不涉及赋值)都被提前到函数底部。在这个例子中被提升到顶部的 scope 声明顶掉了函数体外的全局 scope 声明,因此
console.log()
实际上输出的是一个只是声明没有赋值的变量,所以是
undefined


函数声明提升

函数的两种创建方式

首先函数存在两种声明方式:

函数声明

函数表达式

函数声明:

f('superman');
function f(name){
console.log(name);
}


运行代码可以打印出:
superman


这是因为函数声明 存在函数声明提升,就像变量声明提升一样,这个函数的声明会被提升到外部脚本或者外部函数作用域的顶部。因此可以把函数调用放在函数声明的上面(因为实际上是先提升到顶部的函数声明,再是调用)。

函数表达式:

f('superman');
var f = function(name){
console.log(name);
}


运行代码可以打印出:
TypeError: f is not a function. (In 'f('superman')', 'f' is an instance of HTMLFormElement)
(在 Safari 中是这样,也应该是这样,但是在 chrome 中不报错…)

这种情况之所以报错是因为,函数表达式存在一个变量声明,这个变量声明被提升到了顶部,函数表达式的赋值留在了原地,所以上面的代码相当于:

var f;
f('superman');
f = function(name){
console.log(name);
}


因此会报错。

那么这个例子呢:

var getName = function(){
console.log(2);
}
function getName (){
console.log(1);
}
getName();


最终的结果是
2


分析:第一个是函数表达式,出现了变量声明提升的情况,因此是变量声明被提升到顶部,变量赋值留在原地。第二个是函数声明,整个函数声明被提升到了顶部,当前表现为:

/* 顶部 */
var getName;
function getName (){
console.log(1);
}
/* 顶部 */

getName = function(){ // 函数表达式的赋值被留在了原地,变量声明和函数声明都去了顶部(皆高于这个函数表达式的赋值)
console.log(2);
}
getName();


因此
getName
被后面的函数表达式的赋值给覆盖了,所以输出的是
2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaScript