JavaScript的函数具有两个主要特性,一是函数是一个对象,二是函数提供作用域支持,今天主要聊聊函数的作用域支持。
简单看两个概念:
具名函数表达式
var add = function add (a) {
return a
}
这段代码描述了一个函数,称为‘具名函数表达式’。
如果省略函数表达式中的名字,它就是‘匿名函数表达式’,即匿名函数,例如
var add = function (a, b) {
return a + b;
};
最后看下‘函数声明’
function foo() {
// 函数体
}
函数声明只能出现在“程序代码”中,也就是说在别的函数体内或在全局。这个定义不能赋值给变量或属性,同样不能作为函数调用的参数。
//全局作用域
function foo() {}
//本地作用域
function local() {
function bar() {}
return bar;
}
此时的bar就是在local内,也就是在外面时访问不到的,被称之为局部作用域,那既然这样,我们看下面这段代码
var a = 1;
function aa(){
console.log(a);
}
此时输出的结果是1,很好理解,因为在函数内部访问不到,因此会去外面寻找,直到找到为止
添加一行代码,再看看
var a = 1;
function(){
console.log(a);
var a =2 ;
}
此时输出结果是underfined;很诧异,没有定义之前可以在函数外部访问到,定义了反而访问不了了,实际情况是什么呢,js在函数内部定义的变量会提升至函数体顶部,但仅仅是定义,并未赋值,因此上述代码是这样的
var a = 1;
function(){
var a;
console.log(a);
var a =2 ;
}
既然a定义了,但没赋值,所以console之后当然underfined啦。
既然函数声明会提升,那函数表达式会不会呢,看下面这个例子
// 全局函数
function foo() {
alert('global foo');
}
function bar() {
alert('global bar');
}
function hoistMe() {
console.log(typeof foo);
console.log(typeof bar);
foo();
bar();
function foo() {
alert('local foo');
}
var bar = function () {
alert('local bar');
};
}
hoistMe();
经过上次的代码,这次就比较容易理解了,里面的函数会覆盖外面定义的函数,但是结果都是什么呢
console.log(typeof foo); // "function"
console.log(typeof bar); // "undefined"
foo(); // "local foo"
bar(); // TypeError: bar is not a function
是不是有点诧异呢,仔细想想也很容易明白
刚才说了,函数声明会提前,所以 变量foo和它的定义实现都被提前了,而且函数定义实现和书写顺序无关的,这里故意写在后面也证明了这一点。
但是函数表达式却没有这个技能,所以变量被提前,而定义却没有提前.
谢谢观看