# Execution Sequence Of Function

we are given a piece of code. behold:

function Foo() {
  getName = function() {
    console.log("1");
  };
  return this;
}

Foo.getName = function() {
  console.log("2");
};

Foo.prototype.getName = function() {
  console.log("3");
};

var getName = function() {
  console.log("4");
};

function getName() {
  console.log("5");
}

Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); //  2
new Foo().getName(); // 3
new new Foo().getName(); // 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Analysis

The truly order of execution is under paragraph:

function Foo() {
  getName = function() {
    console.log("1");
  };
  return this;
}

function getName() {
  console.log("5");
}

var getName;

Foo.getName = function() {
  console.log("2");
};

Foo.prototype.getName = function() {
  console.log("3");
};

getName = function() {
  console.log("4");
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Foo.getName()

直接执行 Foo.getName() 输出2

# getName()

当同名的函数表达式与函数在同一个作用域执行时会优先执行函数表达式.

# Foo().getName()

  • 执行Foo(), 将getName 赋给新的函数, 并返回this, 指向全局作用域
  • 执行getName(), 此时已被更改, 输出1

# new Foo.getName()

相当于是构造函数, 输出2

# new Foo().getName()

  • var foo = new Foo()
  • foo.getName() foo本身没有getName方法, 所以会在原型链上去寻找, 输出3

# new new Foo().getName()

  • var foo = new Foo()
  • new foo.getName()foo.getName()当成构造函数又执行了一次而已