栗子1
<script>
var a = 18;
f1();
function f1(){
var b = 9;
console.log(a);
console.log(b);
var a = '123';
};
</script>
JS的解析分为两个阶段:1、预编译期;2、执行期
1、预编译期:对本代码块中的所有声明变量和函数进行处理,需要注意的是,此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值;
2、编译期:从上到下编译代码块
对上述例子进行分析:预编译结果
<script>
var a; // undefined
f1 = function() {
var b; // undefined
var a; // undefined
b = 9; // b = 9
console.log(a); // undefined
console.log(b); // 9
a = '123';
};
a = 18; // a = 18
f1();
</script>
执行结果:undefined,9;
栗子2
function fn(a) {
var a = 1;
function a() {
console.log("a");
}
alert(a);
}
fn(2);
fn这个声明式函数的预编译结果:
function fn(a) {
var a; // undefined 当传参时,变量已经在(a)括号内进行声明
a = function() { // Function
console.log("a");
}
a = 1; // 1
alert(a);
}
// 执行fn(2)后
function fn(a) {
var a;
a = 2;
a = function() {...}
a = 1;
alert(a);
}
// 最后alert(1);
函数类型
1、声明式函数;2、赋值函数;3、匿名函数;4、自执行函数;
声明式函数:
console.log(A); // f A(){}
A(); // "A"
function A() {
console.log("A");
}
注:在 JS 的预编译期间,声明式函数会被先提取出来,然后才按照顺序执行 JS代码
赋值函数:
a();
var a = function() {
console.log("a");
}
编译后结果为:
var a;
a(); // a is not a function
a = function() {...}
匿名函数
function() {
console.log("我是匿名函数");
}
注:直接执行匿名函数,会报错:Uncaught SyntaxError: Function statements require a function name
自执行函数
(function() {
console.log("我是自执行函数");
})()
栗子:
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
预编译:
var name; // undefined
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
name = "Tom";
执行结果为: Goodbye Jack;