1.先来看看这个问题,结果和你心中的答案一样吗?No,Go on!
var a = function b() {}
console.log(typeof a) //function
console.log(typeof b) //undefined
console.log(typeof b()) //Uncaught ReferenceError: b is not defined
分析1:console.log(typeof b) //undefined
首先,不要将函数声明和函数表达式混淆
其次,函数表达式有匿名函数和不匿名函数,上面的就是不匿名函数,但是至于有没有名字都一样,怎么说呢
就像你在浏览器打印一个未声明的变量的类型一样:
再次,如果还想试一试b是什么,就试试看:
就像你在浏览器打印一个未声明的变量一样:
最后,如果你还想试一下如果不是函数表达式,是普通的变量赋值,试试看吧:
那你就会问圈出来的绿色的应该undefined和上面再次中打印结果一样,这下是你想错了,原因是:你试图拿一个 并未声明的变量去使用(就是m=n赋值这块),所以绿色报错的是m=n这行,而不是typeof n这行 还没执行到typeof这 行。(回去再强调一下再次里面的 因为人家是函数表达式 那行不报错 执行typeof)
分析2:console.log(typeof b())//Uncaught ReferenceError: b is not defined
首先,我们知道typeof b()根据优先级问题等价于typeof (b())
其次,我们也知道了b是个未声明,上面打印是b is not defined
再次,我们知道b()执行顺序从左到右,当b是 not defined了 ,直接报错b is not defined,那么再()就不会执行 ,相应的 typeof不会执行。结果已经分析出来了。
最后,再多一嘴,如果定义了一个变量,执行调用 ,结果如下:这也正好对比了未声明和声明变量仿照函数调用报错结构 的区别,哈哈哈
2.其实函数表达式匿不匿名调用,还有函数声明自己看着选择用吧。
//1.函数表达式
//外面这样有名字
var a = function b() {
//里面也可以递归
//b()
//或arguments.callee();
}
a()
//外面这样匿名
var a = function() {
//里面也可以递归
//arguments.callee();
}
a()
//2.函数声明
function b() {
//里面也可以递归
//b()
//或arguments.callee();
}
b()
总结:以上分析过程虽然看起来啰嗦(复杂),但关键一开始我也弄错了,希望我最后的理解能帮助到大家。