Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does assigning to {}.toString mean?

I'm learning JavaScript and I came across this snippet, which demonstrates type detection:

var toClass = {}.toString // Copy a reference to toString for objects into toClass variable

alert( toClass.call( [1,2] ) ) // [object Array]
alert( toClass.call( new Date ) ) // [object Date]

I don't understand what the empty curly brackets are for in the first line, so I remove them like this:

var toClass = toString

And the code still works. But in the following code,

function getAge () {
    alert(this.age);
}

var p1 = {
    age:1
};

var tellAge=getAge;
tellAge.call(p1); //1

if I change var tellAge=getAge to var tellAge={}.getAge, I get an error: cannot read property "call" of undefined. Why is this? Is it because toString is a built-in function?

like image 918
Yibo Yang Avatar asked Sep 16 '15 14:09

Yibo Yang


People also ask

What does toString () method do?

The toString method is used to return a string representation of an object. If any object is printed, the toString() method is internally invoked by the java compiler. Else, the user implemented or overridden toString() method is called. Here are some of the advantages of using this method.

What is the use of toString () in JavaScript?

The toString() method is used internally by JavaScript when an object needs to be displayed as a text (like in HTML), or when an object needs to be used as a string. Normally, you will not use it in your own code.

What happens when you toString an object?

toString() method returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read.

What does toString () do in C#?

ToString is the major formatting method in the . NET Framework. It converts an object to its string representation so that it is suitable for display.


2 Answers

Is it because toString is a built-in function

Not exactly, it is because both Object and window in javascript both have a toString method.


The {} in {}.toString represents a new object in javascript. Object has a toString method and that is what you're creating a reference to.

If you omit the {} it is equivalent of window.toString and as luck would have it the window object itself has a toString method. So everything continues to work.

When you do {}.getAge you're telling the interpreter to get the getAge method from Object, which does not exist, setting tellAge equal to undefined, which leads to the error cannot read property "call" of undefined

like image 131
Jamiec Avatar answered Oct 10 '22 02:10

Jamiec


Oh my... that's a lot of things to answer in such a short time... But you have a long way to go in JavaScript, but you're gonna love it...

1) Object notation. You should google for JSON.

Object notation means, you can define data using a specific format, relevant to JavaScript.

{ } in object notation means, an object... more specifically speaking, this is already an instance of an object.

You could also write this in plain javascript, it would look like this:

new Object()

2) Functions are first class citizens.

Well, functions are indeed a highly valuable asset in the JS ecosystem. That means you can do basically anything you imagine with them. This includes, copying a reference to a function that "belongs" to another object.

{}.toString is a function. You would normally invoke it by doing {}.toString( )

You are instead, just copying the reference to the function in a variable. In this case you "store" the function in the variable "toClass"

3) Prototype chain. You should google, well, prototype chain haha.

Prototype chain, for putting things simple is "like" class inheritance. So that means if a class A has a method "blah" and class B is a "child" class of A, this, well, will also have the method "blah".

In JS world, the top of the prototype chain is "Object". And many functions are already defined in the prototype of Object. Including "toString"

4) General Relativity Problem... a.k.a. this, call, and apply.

As Functions are first class citizens, they basically can exist without even belonging to a specific object instance.

That means, you can choose on which this context you want the function to be invoked on.

By default, when you invoke a functions that seems "attached" to an object, that object becomes the this context of that function call:

{}.toString()    // This executes toString in the context of {}

But as I said, you can just choose where the function is actually executing. For that the methods "call" and "apply" exist.

Our previous example can be translated into:

Object.prototype.toString.call({})  // This executes toString in the context of {}

5) Global objects in your environment.

This is not easy topic, because now JavaScript runs not only on the browser but also on the server... NodeJS is a good example of that.

Assuming you're running this in a browser... there is a global object called window

You can basically call any function in your global object.

So toString is equivalent to window.toString and window is descendent of Object, it will also get the method from the Object.prototype.

Now your answer

getAge is not defined in Object.prototype, so you cannot invoke a non existing function.

like image 45
Adrian Salazar Avatar answered Oct 10 '22 02:10

Adrian Salazar