63

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.

vikrant
  • 2,169
  • 1
  • 21
  • 27
  • *"typeof Object"* Of course, it is a function because this is constructor function. Even `Number`, or `Boolean` are functions. – dfsq Feb 25 '19 at 07:33
  • 2
    Do note that there is a difference between "object" (the concept) and the function "Object". In JavaScript, all functions are objects, including "Object". On the other hand not all objects are functions (eg. `var a = {}`) – TiiJ7 Feb 25 '19 at 07:46
  • 1
    You are doing exactly that, though: `Object.__proto__` => You get the property `__proto__` from `Object`, which is a `function` and thus an `object`. – TiiJ7 Feb 25 '19 at 08:01
  • 3
    You perfectly well can do eg. `Foo.a = 5`. But be aware that this is independent of the variables you declare *inside* the function. The contents of the function are just a block of code that you associate with the function, its scope is *not* the "object" part that you are referring to. – TiiJ7 Feb 25 '19 at 08:15
  • i just checked in chrome console, we can't do that, it will just create a new object Foo and add a new property "a" to it. the original function will remain unchanged. if we could do that, then we should just be able to print the value by console.log(Foo.a), but that doesn't work – vikrant Feb 25 '19 at 08:18
  • 2
    You've messed up something in your tests. It's perfectly legit and working to add a property to a function. For example, jQuery's `$` is a function, but you can call some methods of it, like `$.each()`. – Teemu Feb 25 '19 at 08:21
  • okay, after you add a property, how do check if the property is inside the function, consider this function: foo(){var a =1}. now can i access a like foo.a ? – vikrant Feb 25 '19 at 08:23
  • See a [fiddle](https://jsfiddle.net/oy7kmwf8/). In your example in the comment, you can't access _a local variable_ outside of the function, but when creating _a property_ to the function, it's accessable both inside and outside of the function. – Teemu Feb 25 '19 at 08:28
  • please see this fiddle: https://jsfiddle.net/rs2y1qg9/. – vikrant Feb 25 '19 at 08:30
  • Please don't mess local variables with function properties, they are not the same. – Teemu Feb 25 '19 at 08:30
  • The (almost) only difference between a regular object and a function is, that a function object has the internal [[callable]] flag set. – Teemu Feb 25 '19 at 08:33
  • @Teemu okay, i get it now, thanks – vikrant Feb 25 '19 at 08:33
  • 2
    Just to make it sure, see [another fiddle](https://jsfiddle.net/oy7kmwf8/1/) = ). – Teemu Feb 25 '19 at 08:36
  • @Teemu just one more question , consider this fiddle, https://jsfiddle.net/rs2y1qg9/2/ why doesn't the this keyword work inside when i call the function?i understand that `this` must point to an object, but if the function is an object, then the context should be set for this – vikrant Feb 25 '19 at 08:45
  • In a traditional function call `this` refers to the object before the method name, i.e. when calling `object.Foo();`, `this` in `Foo` method refers to `object`. When you just call `Foo();` you're not defining the context. – Teemu Feb 25 '19 at 10:10
  • I recommend this answer https://stackoverflow.com/a/24811539/277304 – leonbloy Feb 25 '19 at 15:45
  • @leonbloy That answer (talking about "units") is rubbish. Did you link the right one? – Bergi Feb 25 '19 at 17:06
  • This sounds very much like a duplicate of https://softwareengineering.stackexchange.com/questions/369631/unable-to-solve-mystery-of-functions-in-javascript/369666#369666 – Eric Lippert Feb 26 '19 at 07:43
  • You've asked a half dozen questions here. **Please try to focus only on one question at a time**. – Eric Lippert Feb 26 '19 at 07:45

7 Answers7

80

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.

TiiJ7
  • 3,332
  • 5
  • 25
  • 37
  • @TiiJ7 i have one small doubt though, if i do `typeof(Function.prototype)`, output: "function". is it just referring to Function.prototype.constructor? – vikrant Feb 25 '19 at 18:49
  • 2
    @vikrant `prototype` is just a property of the function `Function`. And apparently it was defined as a function itself. Objects can have functions in their properties, and since `Function` is a function (and thus an object), it works for that too. I don't know why they decided to make `Function.prototype` also a function, but it doesn't really matter since a function can do anything an object can. – TiiJ7 Feb 25 '19 at 19:01
  • 1
    thanks for the answer, i did check the ECMAScript spec, they have mentioned a reason regarding this as " The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification." https://tc39.github.io/ecma262/#sec-function-instances-prototype – vikrant Feb 25 '19 at 19:28
18

Function and Object are both constructor functions which can be used to create a function and an object, respectively, which is the reason typeof Function returns function.

About how functions and objects are related in javascript, consider the following points:

  1. All non-primitive types are objects in JavaScript.
  2. All objects directly or indirectly inherit from Object.prototype (unless prototype is changed explicitly using setPrototypeOf).
  3. All native functions inherit from Function.prototype which inherits from Object.prototype, so it means function indirectly inherits from Object.prototype because functions are treated as objects in JavaScript.
  4. The reason functions are treated as objects is because they can be passed as parameters to other functions and can be returned from functions i.e. higher order functions(a powerful feature of javascript).
  5. A function can be called using the () operator because the JavaScript engine knows it is declared using a function keyword and has executable code. So whenever it is called, the JavaScript engine creates a new execution context and set the this binding and then executes the function. None of that happens when you try to call an object instead an error is thrown i.e. "is not a function".

    So we can say that not every object is a function because they may have not been declared using the function keyword and not have executable code.

  6. As the function is treated as an object in JavaScript, we can add properties to it, create new objects from it.
  7. A non-function type object cannot be called using () because it does not have executable code and is not declared using the function keyword. Instead, it is declared using new Object() or object notation and contains methods and properties.

I hope it clears both questions.

Nabil Shahid
  • 1,448
  • 8
  • 11
  • No. Not all objects inherit from `Object.prototype`, not all functions inherit from `Function.prototype`. Functions are callable because that's their intrinsic feature (what makes these objects functions), not because they inherit from `Function.prototype`. Similarly, objects can have properties because that's what defines an object, not because they inherit from `Object.prototype`. The inheritance chain (whose mere *existence* is another feature of being an object) only influences which inherited properties/methods are accessible, but does not otherwise affect the kind of value. – Bergi Feb 25 '19 at 16:40
  • @Bergi What functions do not inherit from Function.prptotype? Also i said "A function can be called using () operator because javascript engine knows it is declared using a function keyword and it inherits from Function.prototype and have executable code" not only because it inherits from Function.prototype. – Nabil Shahid Feb 25 '19 at 17:31
  • `var f = Object.setPrototypeOf(function() {…}, null); f()` for example. Yes, you didn't say "only because", but you said "because" - and the inheritance is not related at all to whether it can be called. "has executable code" is the only criterion. – Bergi Feb 25 '19 at 18:05
  • @Bergi Thanks for the explanation. I have edited the answer accordingly. – Nabil Shahid Feb 25 '19 at 19:04
16

Q1: Why are they pointing to Function?

A1: Because they are functions. Function and Object are just constructor functions.

function is a Function object. object is an Object object.

Q2: If everything is an object in JavaScript, then why is Object a function?

A2: Because Object is just a constructor function.

typeof Object
// 'function'
typeof new Object()
// 'object'

And a function is an instance of Function, so that makes a function an object.

(function(){}) instanceof Function
// true
zmag
  • 7,825
  • 12
  • 32
  • 42
10

Fundamentally

Functions has some code that can be executed.
Object are those which contains data.

For class Point having x and y.

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    isOrigin() { return x == 0 && y == 0; }
}
let p = new Point();

Answer 1

In this, p is object which contains data or other functions.

p.isOrigin is function.

Similarly, class Point is itself a function which when runs produces p. That's why all classes like Object and Functions are functions more precisely constructor functions.

Answer 2

If everything is an object in JavaScript, then why is Object a function?

Same as Answer 1.

Also, how is a function actually implemented inside JavaScript?

Different JavaScript engines will have different implementations. They have specifications which they need to follow.

What happens to the variables declared inside a function?

Off topic. Every function runs with a scope which holds all data for that functions.

Is a function converted into an object by the JavaScript compiler?

Not sure what are you asking.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
amitdigga
  • 6,550
  • 4
  • 26
  • 31
  • 1
    Close this question if answered. Ask another question. `this` keyword itself is a huge topic. https://medium.com/quick-code/understanding-the-this-keyword-in-javascript-cb76d4c7c5e8 – amitdigga Feb 25 '19 at 09:03
6

The ECMAScript reference is very nice for answering such questions.

Hence, to answer your question: Foo can be nothing but an object (because everything else on the menu is a basic value type). Hence, Foo() is a special syntax which simply invokes the internal Call method of that object. But Foo itself is an object through and through, you can do with it everything else you can do with any other object, including setting arbitrary attributes on it.

Having a method defined on an object simply means that there is an attribute with that name, and the attribute references an object, which happens to be a "function object".

Something which can be used as a constructor is, again, simply an object which happens to have a Construct internal method, and the syntactic sugar to call it.

As you know, there are no classes in JavaScript, it's a prototype-based object-oriented language (it's as object-oriented as you can get, it literally has nothing else). So any kind of "prototype" is just a link between objects. A constructor method (as explained in the link given above) simply calls the constructor method with the object on which it was called (i.e., something like String) as an argument, just like the language would call Call with this being the object the method has been invoked on.

AnoE
  • 8,048
  • 1
  • 21
  • 36
5

Object is the constructor function of all objects. So, typeof Object==="function"

Here is a snippet for visualisation:

console.log(typeof Object)            //function (which is an object)
var object=new Object()               //An instance of Object 'class'
console.log(typeof object)            //object
console.log(object instanceof Object) //true, because object is created by Object()

Function is the constructor function of all functions (including itself...)

So, although not everything is a function, but most of the Uppercase native identifiers refer to a constructor function.

FZs
  • 16,581
  • 13
  • 41
  • 50
4

Yes, Object is of type function. It is a class/Function implementation which when invoked with new (new Object()) will result in an object with allocated memory.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131