Javascript编程笔记一:理解变量和函数提前声明

本文主要讨论问题:

  • 为什么需要明白变量和函数提前声明?
  •  为什么变量会被提前声明?
  •  为什么函数会被提前声明?

一,为什么需要明白变量和函数提前声明?
Javascript是中弱语言,允许先使用,后声明变量或函数编程,对于习惯c语音,java,c++的人,如果不理解javascript语言的变量和函数提前声明,会感到很困扰,运行代码结果不是想要的结果。网上用的是“函数提升”,我想用指函数被提前声明表达更准确。

二,如何理解变量和函数被提前声明?
首先理解变量概念

1,变量的定义

可以使用var定义变量,变量如果没有赋值,那变量的初始值为undefined

2,变量的作用域

变量作用域指:变量起作用的范围。

变量分为全局变量和局部变量。

全局变量在全局都拥有定义;而局部变量只能在函数内有效。
在函数体内,同名的局部变量或者参数的优先级会高于全局变量。也就是说,如果函数内存在和全局变量同名的局部变量或者参数,那么全局变量将会被局部变量覆盖。
所有不使用var定义的变量都视为全局变量

3,变量提前

变量提前:指变量提前声明了

var name = "Baggins";
(function () {
 console.log("Original name was " + name);// "Original name was undefined"
 var name = "Underhill";
 console.log("New name is " + name);// "New name is Underhill"
})();

上述代码中,我们先声明了一个变量 name ,我们的本意是希望在第一次打印 name 变量时能够输出全局范围内定义的 name 变量,然后再在函数中定义一个局部 name 变量覆盖全局变量,最后输出局部变量的值。可是第一次输出的结果和我们的预期完全不一致,原因就是我们定义的局部变量在其作用域内被“提前”了,也就是变成了如下形式:

var name = "Baggins";
(function () {
 var name; //注意:name 变量被提前了!
 console.log("Original name was " + name);// "Original name was undefined"
 name = "Underhill";
 console.log("New name is " + name);//"New name is Underhill"
})();


4,函数提升(提前)

类似变量提前

函数的“被提前”还要分两种情况,

第一种:函数声明,

第二种:函数作为值赋值给变量,也即函数表达式。

先说第一种情况,上代码:

isItHoisted();//"Yes!"
function isItHoisted() { 
 console.log("Yes!");
}

如上所示,JavaScript 解释器允许你在函数声明之前使用,也就是说,函数声明并不仅仅是函数名“被提前”了,整个函数的定义也“被提前”了!所以上述代码能够正确执行。

再来看第二种情况:函数表达式形式。还是先上代码:

Hoisted();// "Definition hoisted!"
NotHoisted();// TypeError: undefined is not a function
function Hoisted() { 
 console.log("Definition hoisted!");
}
var NotHoisted = function () { 
 console.log("Definition not hoisted!");
};

我们做了一个对比,Hoisted 函数被执行了,符合第一种类型;NotHoisted 变量“被提前”了,但是他的赋值(也就是函数)并没有被提前,从这一点上来说,和前面我们所讲的变量“被提前”是完全一致的,并且,由于“被提前”的变量的默认值是 undefined ,所以报的错误属于“类型不匹配”,因为 undefined 不是函数,当然不能被调用。


总结:

变量的声明被提前到作用域顶部,赋值保留在原地
函数声明整个“被提前”
函数表达式时,只有变量“被提前”了,函数没有“被提前”


参考资料地址:

http://www.jb51.net/article/74901.htm







你可能感兴趣的:(Javascript编程笔记一:理解变量和函数提前声明)