js学习之js函数hacker - mowatermelon/studyNode GitHub Wiki
Fn(); //执行结果:console.log在控制台打印提示
function Fn(){ //声明式函数
console.log("执行了定义式函数");
}
Fun(); //执行结果:程序报错,提示函数未定义
var Fun= function(){ //赋值式函数
console.log("执行了赋值式函数");
} JS的解析过程分为两个阶段:预编译期(预处理)与执行期,页面加载过程中,浏览器会对页面上或载入的每个js代码块(或文件)进行扫描,如果遇到定义式函数,则进行预处理(类似于C等的编译),处理完成之后再开始由上至下执行;遇到赋值式函数,则只是将函数赋给一个变量,不进行预处理,待调用到的时候才进行处理。
代码块是指一对<script type="text/javascript"></script>标签包裹着的JS代码,文件就是指通过src导入页面的JS文件。
浏览器对每个代码块或文件进行独立的扫描,然后对全局的代码进行顺序执行。所以,在一个代码块(文件)中,函数可以在调用之后进行定义式定义(如案例一中的Fn()),但在两个独立的代码块中,定义函数所在的代码块必须在函数被调用的代码块之前。
<script type="text/javascript">
function Fun(){
console.log("Hello World!");
}
</script><script type="text/javascript">
Fun();//控制台顺利打印,因为函数所在代码块在上一个代码块
Fn(); //报错,提示函数未定义,因为函数所在代码块在下一个代码块
</script><script type="text/javascript">
function Fn(){
console.log("Hello World!");
}
</script>因为在JS中重名的函数,后定义的会覆盖前面定义的函数,这种策略和JS的顺序执行也是有关系的。
fn(); //控制台打印提示 2
function fn(){
console.log(1);
}
function fn(){
console.log(2);
}
fn(); //控制台打印提示 2body中内部的函数会先于onload的函数执行,body的onload事件触发条件是body内容加载完成,而body中的JS代码会在这一事件触发之前运行。
function fnOnLoad(){
console.log("I am outside the Wall!");
}
window.onload = fnOnLoad;
console.log("I am inside the Wall..");
//先在控在控制台打印"I am inside the Wall.."
//后在控制台打印"I am outside the Wall!" 严格来说,JS是没有多线程概念的,所有的程序都是单线程依次执行的。 延时执行、Ajax异步加载只是看起来像多线程。
function fn1(){
setTimeout(function(){
console.log("我先调用")
},1000);
}
function fn2(){
console.log("我后调用");
}
fn1();
fn2();
// 先在控制台打印:“我后调用”,
// 1秒后在控制台打印:“我先调用” 看上去,fn2()和延时程序是分两个过程再走,但其实,这是JS中的回调机制在起作用,类似于操作系统中的中断和响应 —— 延时程序设置一个中断,然后执行fn2(),待1000毫秒时间到后,再回调执行fn1()。
同样,4中body的onload事件调用的函数,也是利用了回调机制——body加载完成之后,回调执行fnOnLoad()函数。
Ajax请求中的数据处理函数也是一样的道理。
参考网站