js学习之js函数hacker - mowatermelon/studyNode GitHub Wiki

  • 1 定义式函数与赋值式函数

    Fn();  //执行结果:console.log在控制台打印提示
    function Fn(){   //声明式函数
        console.log("执行了定义式函数");  
    }          

    Fun();  //执行结果:程序报错,提示函数未定义 
    var Fun= function(){   //赋值式函数
        console.log("执行了赋值式函数");  
    }   

JS的解析过程分为两个阶段:预编译期(预处理)执行期,页面加载过程中,浏览器会对页面上或载入的每个js代码块(或文件)进行扫描,如果遇到定义式函数,则进行预处理(类似于C等的编译),处理完成之后再开始由上至下执行;遇到赋值式函数,则只是将函数赋给一个变量,不进行预处理,待调用到的时候才进行处理。

  • 2 代码块及js文件的处理

代码块是指一对<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>
  • 3 重复定义函数会覆盖前面的定义

因为在JS中重名的函数,后定义的会覆盖前面定义的函数,这种策略和JS的顺序执行也是有关系的。

fn(); //控制台打印提示 2
function fn(){ 
    console.log(1); 
} 
function fn(){ 
    console.log(2); 
} 
fn(); //控制台打印提示 2
  • 4 body的onload函数与body内部函数的执行

body内部的函数会先于onload的函数执行,bodyonload事件触发条件是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!" 
  • 5 JS是多线程or单线程?

严格来说,JS是没有多线程概念的,所有的程序都是单线程依次执行的。 延时执行Ajax异步加载只是看起来像多线程

function fn1(){ 
    setTimeout(function(){ 
    console.log("我先调用") 
    },1000); 
} 
function fn2(){ 
    console.log("我后调用"); 
} 
fn1(); 
fn2(); 
// 先在控制台打印:“我后调用”, 
// 1秒后在控制台打印:“我先调用” 

看上去,fn2()和延时程序是分两个过程再走,但其实,这是JS中的回调机制在起作用,类似于操作系统中的中断和响应 —— 延时程序设置一个中断,然后执行fn2(),待1000毫秒时间到后,再回调执行fn1()。 同样,4中bodyonload事件调用的函数,也是利用了回调机制——body加载完成之后,回调执行fnOnLoad()函数。 Ajax请求中的数据处理函数也是一样的道理。

参考网站

⚠️ **GitHub.com Fallback** ⚠️