Search code examples
javascriptprototype

Is `Object` a function in JavaScript?


Consider this function:

function Foo(){
    var a = "3";
};

According to __proto__ VS. prototype in JavaScript,

Foo.__proto__ = Function.prototype
Function.prototype.__proto__ = Object.prototype

I understood that part, but if I do this in the Google Chrome console:

Object.__proto__
output: ƒ () { /* native code */ }

Function.__proto__
output: ƒ () { /* native code */ }

Q1: Why are they pointing to Function? What actually are Function and Object and how are they different from each other, because Object is actually a function?:

typeof Object
"function"

Q2: If everything is an object in JavaScript, then why is Object a function? Also, how is a function actually implemented inside JavaScript? What happens to the variables declared inside a function? Is a function converted into an object by the JavaScript compiler?

Sorry if I am missing something obvious. I am really confused by the way function and object are implemented in JavaScript.


Solution

  • You seem to be confused between "object" (the data structure) and Object (the function).

    An object is a concept in JavaScript that is a generic container for some data. An object contains properties with keys and associated values.

    In JavaScript, everything that is not a primitive is an object. This includes functions, which are basically a special type of object that can be "called" with the () syntax.

    JavaScript provides a number of built-in functions that have various purposes. Two such functions happen to be called Object and Function. So in other words Object is a function and thus also an "object" (data structure).

    Let's take your function Foo as an example:

    function Foo() {
        var a = "3";
    }
    

    Foo is a function. This means that Foo can be called, eg. var f = Foo(). In this case f will be undefined since Foo doesn't return anything.

    Because Foo is a function, it is also an object. This means we can also add and read properties from it:

    Foo.bar = 5;
    Foo.bar++;
    console.log(Foo.bar); // prints 6
    

    Please note that this "object" part of Foo is not related to the contents of the function. That means that the code you declared (var a = "3") is irrelevant. You cannot access var a in any way here because it does not exist until you call the function. If you were to do Foo.a, you are not manipulating var a inside the function; you are working with the property a on the object Foo.

    You can however do it the other way around and access properties on Foo inside of the function:

    function Foo() {
        var a = "3"; // a is local to this scope, you cannot get to it from outside
        console.log(a); // prints 3 - local variable a is accessible inside the scope of this function
        console.log(Foo.a); // prints 5 - a is a property on object Foo, and is accessible here
    }
    // var a inside Foo cannot be accessed here
    Foo.a = 5;
    Foo();
    

    Edit: Re. your question regarding "this" in the comments. this is a special keyword in JavaScript that refers to an object. However, this object is not the function itself, it is a new object that is created when you call a function using the new keyword:

    function Bar() {
        this.a = 10;
        console.log(this == Bar); // prints false
    }
    var bar = new Bar();
    console.log(bar.a); // prints 10
    

    A function that is meant to be called with the new keyword is referred to as a "constructor function". Object and Function are both examples of constructor functions, which is why their names start with an uppercase letter (a convention in JavaScript).

    When you create an object with a constructor function, the property prototype of this function is used as the prototype (accessible through __proto__) of the created object.

    console.log(bar.constructor == Bar) // prints true
    console.log(bar.__proto__ == Bar.prototype) // prints true
    

    this is also used for other things, but that is a broad subject and way out of scope for this question.