The title is as follows:

function Foo() {
    getName = function() { alert(1); }
    return this
}
Foo.getName = function() { alert(2); }
Foo.prototype.getName = function() { alert(3); }
var getName = function () { alert(4); }
function getName() { alert(5); }

/ / the output value
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName()
new Foo().getName()
new new Foo().getName()

// The output is
/ / 2
/ / 4
/ / 1
/ / 1
/ / 2
/ / 3
/ / 3
Copy the code

The output values are analyzed below:

  1. Foo.getname (), which accesses a static property on function Foo, outputs 2.

    Now, attempts to define getName inside a function and bind getName to Foo prototype fail to execute foo.getName (), while creating an object as if it were a literal object would execute getName() normally.

Running the getName() definition by creating an object does not work inside a function, even if it is a global variable.

Conclusion: Since functions themselves are objects, they are static methods with function-binding properties and methods and can be called directly. Properties and methods bound to the stereotype cannot be called until the object is created; methods defined inside the constructor object cannot be called through the object.

  1. getName(); The resulting output is 4 instead of 5. This is because JS has variable declaration promotion (all declared variables or declared functions are promoted to the top of the current function).

    Therefore, the code execution sequence is:

    var getName;
    function getName() { alert(5); }
    / /... Omit code
    getName = function () { alert(4)}Copy the code

    The final getName output is 4

    Extend the topic:

    console.log( Foo )
    function Foo() {
        console.log(1);
    }
    var Foo = 1
    Copy the code

    The output of Foo is?

  2. Foo().getName(); The output value is 1. Foo() is executed to define the global variable getName, and the getName() method of the global object is called to return 1.

    Note that Foo() returns this to the global object Window, so global object getName() is called. GetName in the function is bound to a global object, and a call to Foo will report an error.

    Node does not have a global object window, so getName cannot be called

  3. GetName () calls the global function and returns 1 because Foo() updates the value of getName.

  4. New foo.getName () looks at the precedence of the operator. . Takes precedence over new, which is equivalent to executing new (foo.getName)(), which is equivalent to executing the constructor of getName, which returns 2

  5. New Foo().getName() executes (new Foo()).getName() as Foo, and then executes getName(). New Foo() returns the newly created empty object. Since the object is not yet bound to the property getName, the prototype getName is called and returns 3

    Note that the constructor return this, when new is executed, returns the newly created object.

    Extend the topic:

    function A() {
        this.a = 2;
        function B() {
            this.a = 1;
        }
        return B();
    }
    console.log(new A());
    Copy the code

    What is the value of a? If return new B(); What is the value of a?

  6. New new Foo().getName() can be rewritten as new ((new Foo()).getName)() initializes the instance and then executes getName() on the prototype object as a constructor, returning 3

The final code can be optimized to

var getName;
function getName() { alert(5); }
function Foo() {
    getName = function() { alert(1); }
    return this
}
Foo.getName = function() { alert(2); }
Foo.prototype.getName = function() { alert(3); }
getName = function () { alert(4); }

Foo.getName(); / / 2
getName(); / / 4
Foo();
getName(); / / 1
getName(); / / 1
Foo.getName(); / / 2
(new Foo()).getName(); / / 3
(new Foo()).getName(); / / 3
Copy the code