上述两种方式除了定义的语法不同之外,最主要的区别是函数声明具有【函数声明提升】的特点,将函数声明提升到作用域顶端,意思是在执行代码之前会先读取函数声明,也就是说可以把函数声明放在函数调用的后面。
例子1:
test()//弹出hello,因为【函数声明提升】的特点,函数调用之前,已经读取了该函数完成了声明function test(){
alert("hello")
}
例子2:
test()//报错:Uncaught ReferenceError: test is not defined//因为【函数表达式】不具备提升的特点,在函数调用时,作用域中还未读取该函数的定义
//作用域读取函数表达式是按照代码顺序读取
var test = function(){
alert("hello")
}
test()//弹出hello
例子3:
if(condition){function test(){
alert("hello")
}
}else{
function test(){
alert("world")
}
}
//弹出world,因为函数声明在代码执行前就已经完成了,作用域已经完成了对该函数的读取,与条件无关
//同名函数声明,后面的会覆盖前面的
test()
if(condition){
var test2 = function(){
alert("hello")
}
}else{
var test2 = function(){
alert("world")
}
}
//弹出内容与条件相关,作用域读取函数表达式是按照代码执行顺序读取的
test2()
例子4:
//函数表达式var test = function(){
alert("hello")
}
//第一次调用
test()
//变量声明
var s = "world"
//函数声明
function test(){
alert(s)
}
//第二次调用
test()
//解释:两次调用都将弹出hello,在代码执行前方式二已经被作用域读取,然后执行方式一代码,方式一的test覆盖方式二的test,然后执行两次调用弹出hello
javascript虽然是解释执行的语言,但也会进行预编译。
if(condition){function sayHi(){
alert("Hi!")
}
}else{
function sayHi(){
alert("Yo!")
}
}
这种形式,JS引擎在预编译的过程中会注册方法到window对象下,就是window.sayHi。
而不会顾及if else条件,导致重复的sayHi方法被注册,在这种情况下是无效语法。
var sayHiif(condition){
sayHi=function sayHi(){
alert("Hi!")
}
}else{
sayHi=function sayHi(){
alert("Yo!")
}
}
而下面这种是作为一个 变量(而非函数function),变量是可以被重复赋值的,所以语法不会有问题。
不知道有没有说清楚。