函数声明(funDeclaration)
无论在哪儿定义函数,只要是外层函数并且满足不被包裹,就都可以进行全局范围的调用
function foo() { }
在函数体内部的函数声明无法提升到全局,只能提升到函数体内顶部(块级作用域空间)
function test() {
console.log(1);
function test2() {
console.log(2);
}
}
test(); // 1
test2(); // Uncaught ReferenceError: test2 is not defined
函数体内部执行:
function test() {
test2();
function test2() {
console.log(2);
}
}
test(); // 2
在外部要想访问函数内部申明的函数,需要先return
出来:
function test() {
console.log(1);
function test2() {
console.log(2);
}
return {
test2:test2
}
}
test().test2(); // 2
函数表达式(funExpression)
函数表达式需要等到表达式赋值 完成 才可以
换言之使用var来声明函数,就会涉及到变量的声明提升,先拿出变量名定义为undefined,再随着逻辑顺序进行赋值先定义,后使用
var foo = function () { }
demo1
Toast() // hello world
showToast(); // shwoToast is not a function
var showToast = function () {
console.log('123')
}
function Toast() {
console.log('hello world')
}
在这里只需要把showToast
提前就好了
demo2
主流浏览器解析,ie11+
var sayHello;
console.log(typeof (sayHey));//=>undefined
console.log(typeof (sayHo));//=>undefined
if (true) {
function sayHey() {
console.log("sayHey");
}
sayHello = function sayHo() {
console.log("sayHello");
}
} else {
function sayHey() {
console.log("sayHey2");
}
sayHello = function sayHo() {
console.log("sayHello2");
}
}
sayHey();// => sayHey
sayHello();// => sayHello
在花括号里面声明的函数在进行预解析时只会提升函数名,不会提升函数体,所以不管if条件是否为真,函数体都不会提升,永远是undefined,接下来随着if条件判断进行解析赋值,当然是走ture方法。
ie9,ie10
var sayHello;
console.log(typeof (sayHey));//=>function
console.log(typeof (sayHo));//=>undefined
if (true) {
function sayHey() {
console.log("sayHey");
}
sayHello = function sayHo() {
console.log("sayHello");
}
} else {
function sayHey() {
console.log("sayHey2");
}
sayHello = function sayHo() {
console.log("sayHello2");
}
}
sayHey();// => sayHey2
sayHello();// => sayHello
在这里的ie将所有的函数声明进行了提升,从而由sayHey2
替代了sayHey
,函数表达式的在顺着条件判断进行了定义,执行为true
的情况,进行赋值解析。
ie8
var sayHello;
console.log(typeof (sayHey));//=>function
console.log(typeof (sayHello));//=>function
if (true) {
function sayHey() {
console.log("sayHey");
}
sayHello = function sayHo() {
console.log("sayHello");
}
} else {
function sayHey() {
console.log("sayHey2");
}
sayHello = function sayHo() {
console.log("sayHello2");
}
}
sayHey();// => sayHey2
sayHello();// => sayHello
ie8在这里处理的比较奇葩,正常的函数申明提升,但是却也将条件判断为假的情况进行了提升,我们看到typeof (sayHello)=>function
结论
由于函数声明提升的差异,想要在条件判断中定义不同的函数方法,应该采用定义函数表达式的方法,这样就在各个浏览器中拿到相同的函数方法,得到相同的结果。
var sayHello;
console.log(typeof (sayHey));//=>undefined ie8以下解析为function
console.log(typeof (sayHo));//=>undefined
if (true) {
var sayHey =function sayHey() {
console.log("sayHey");
}
} else {
var sayHey =function sayHey() {
console.log("sayHey2");
}
}
sayHey();// => sayHey
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。