Js整理备忘(补充)——函数的执行顺序

Javascript中函数的执行时顺序是怎样的呢??以下几个例子应该可以说明:

1、先看第一个例子,思考:输出结果是什么呢?

<script type="text/javascript">
    function print(msg) {
        document.write(msg + "<br/>");
    }   
    function f() {
        this.s = "hello";
        print(this.s);
    }
    f();
    function f() {
        this.s = "nihao";
        print(this.s);
    }
    f();
    var f = function() { 
        this.s = "a new string";
        print(this.s);
    }
    f();     
</script>

——这里定义了三个同名的函数f,在三个不同的地方进行调用,输出结果为:

nihao
nihao
a new string

跟预想的结果一样吗?不难发现这里定义函数用了两种方法,根据结果分析一下:

第一种使用function定义,这种方式定义的函数,在Js解释器运行时就被解析,在哪里调用都可以(只要是在其作用域内)。

第二种使用函数直接量定义,并将该函数的引用赋给一个变量,这样的函数必须先定义再调用,在将要开始调用时才会被动态解析。

也就是说,本例中的执行顺序为:

<1>解析时,第一第二个函数体都被解析,但由于同名,所以被第二个覆盖,第三个函数此时不解析。

<2>解析完成后,再从上往下按顺序执行代码,遇到第一个调用语句f(),监控窗口显示,此时匹配的是第二个函数体,故第一行输出“nihao”。参见下图1。

<3>继续往下,遇到第二个调用语句f(),可见此时匹配的仍然是第二个函数体,故第二行也输出“nihao”。参见下图2。

<4>继续往下,遇到第三个调用语句f(),可见此时匹配的变成第三个函数体。可知第三个函数体在定义的下方遇到调用函数时才会被动态解析。参见下图3。

<5>继续单步执行,则进入第三个函数体内,输出最后的结果,如图4所示。

1 2 3 4

这样一来,整个过程就一目了然了。有兴趣不妨自己试一试。

2、为了巩固一下自己得出的结论,下面将例子稍微作了一点修改,如下:(如果已经完全理解,则可以就此打住)

var f = function() {
    this.s = "hello";
    print(this.s);
}
f();
var f = function() {
    this.s = "nihao";
    print(this.s);
}
f();
var f = function() { 
    this.s = "a new string";
    print(this.s);
}
f();

——只是将函数都按照第三种方法用var语句进行定义。结果输出如下:

hello
nihao
a new string

应该跟预想结果一样的吧。利用var语句将定义的函数赋给一个变量,那么函数将在即将调用的时候才会被解析,并执行已解析的匹配的函数体。

单步运行过程截图,直接参加图上的说明:

5  6  7

3、如果还不是很清楚,可以再稍微将代码作一些修改,如下:

var f = function() {
    this.s = "a new string";
    print(this.s);
}
f();
function print(msg) {
    document.write(msg + "<br/>");
}   
function f() {
    this.s = "hello";
    print(this.s);
}
f();
function f() {
    this.s = "nihao";
    print(this.s);
}
f();  

——将使用var语句定义的函数放在第一个。结果输出如下:

a new string
a new string
a new string

与预想中的结果一样吗?三次调用都执行了用var语句定义的函数。

这是因为下面两个用function定义的函数先被解析,当解析完成,遇到第一个函数调用语句f()时,第一个函数体才开始被解析,于是覆盖了之前解析的下面两个同名函数。于是下面的函数调用语句f()都只执行第一个函数体。终于明白了吧~~(^_^)

原文地址:https://www.cnblogs.com/gppblog/p/1647997.html