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(); //控制台打印提示 2
body
中内部的函数
会先于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请求
中的数据处理函数也是一样的道理。
参考网站