看题:
b = 1;
(function b() {
b = 2;
console.log(b);
})();
console.log(b);
答案是多少?大部分人会说2和1,但是答案是:
function b(){
b=2;
console.log(b)
} 和 1 。
为什么呢?下面来分析下。
对于第二次打印的结果,比较容易回答,这里用到了自执行函数和闭包,就不详细解释了。总的来说就是函数外层的console访问不到函数内部的变量,所以只能是1。
对于第一次打印的结果,这里运用到了函数声明,先来讲解下什么是函数声明和函数表达式:
函数声明:
关于函数声明的方式,它的一个重要的特性就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句后面。像下面这样的,
function b() {
b = 2;
console.log(b);
}
函数表达式:
函数表达式有多种表达方式,下面是最常见的一种,
var b =function () {
b = 2;
console.log(b);
}
接下来继续说,由于此题的变量没有带var,即没有变量的声明,也就没有变量作用域的提升,只是单纯的赋值。也不存在函数声明的提升,闭包的影响。下面到重点了,如果在函数内部加上“use strict”(开启严格模式) 这句话,就会出现另外一个现象,上图:
这是谷歌的报错,
这是火狐的报错。
两者的意思就是说b是一个只读属性,此时b指的是函数的名字,不能被修改,所以报错了。
补充:今天又看到了一个例子,也是这种情况。
b = function c() {
"use strict";
c = 3;
console.log(c);
};
b();
注意:这种情况存在于自执行函数和函数声明及函数表达式混合的命名方式中。