Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does this in this snippet?

I am reading You Don't Know JS: ES6 & Beyond and I encountered this snippet in Symbol.species section.

class Cool {
    // defer `@@species` to derived constructor
    static get [Symbol.species]() { return this; }

    again() {
        return new this.constructor[Symbol.species]();
    }
}

class Fun extends Cool {}

class Awesome extends Cool {
    // force `@@species` to be parent constructor
    static get [Symbol.species]() { return Cool; }
}

var a = new Fun(),
    b = new Awesome(),
    c = a.again(),
    d = b.again();

c instanceof Fun;           // true
d instanceof Awesome;       // false
d instanceof Cool;          // true

It seems like the function Symbol.species{ return Something } should always return a constructor function. But in the first presence of this function: static get [Symbol.species]() { return this; } I am confused because I always think this should be an object instead of a constructor function. Could you please help me to clarify the facts?

And about return new this.constructor[Symbol.species]();, what does this here refer to?

like image 826
krave Avatar asked May 22 '16 05:05

krave


People also ask

What does it mean by snippet?

Definition of snippet : a small part, piece, or thing especially : a brief quotable passage.

What is a snippet example?

a small and often interesting piece of news, information, or conversation: I heard an interesting snippet on the radio this morning. I love listening to snippets of conversation in restaurants.

How do you use snippet in a sentence?

(1) He passed on any interesting snippets of information he could glean from his colleagues. (2) I heard an interesting snippet on the radio this morning. (3) I love listening to snippets of conversation in restaurants. (4) Have you got any interesting snippets for me?

What is the use of snippet?

Snippets are short, reusable text blocks that can be used on contact, company, deal and ticket records, in email templates, in chat conversations, and when logging an activity or note. If you want to create reusable emails, learn more about the templates tool.


1 Answers

this will refer to something different inside a method depending on the context it was executed.

In class methods, static methods, this will refer to the class.

So for instance with

static get [Symbol.species]() { return this; }

Since this is a class method, it will is executed on the class and this will refer to the class

//since this is a getter we don't use trailing `()`
Cool[Symbol.species] === Cool;
//It does not exist on instances
var myCool = new Cool();
console.log( myCool[Symbol.species] );
//will give undefined

Now for instance methods, like the again method, they only exist on the instance and so are called from the instance and not the class:

console.log( Cool.again );
//will give undefined
var myCool = new Cool();
var newInstance = myCool.again();

In instance methods this refers to the instance, not the class.

So given:

 return new this.constructor[Symbol.species]();
  • this is the instance (eg, new Cool)
  • this.constructor is the constructor that created the instance (eg, Cool)
  • this.constructor[Symbol.species] is the class getter method Symbol.species
  • new this.constructor[Symbol.species]() is a new instance of the class that Symbol.species returned

So the whole line is returning a new instance of a class that the static getter Symbol.species method returns.

This allows a class to have methods that create new instances of a class without knowing its name.

So as the example shows, even though Fun never defined it's own again method again knows how to create a new instance of Fun. And as Awesome shows you can just override Symbol.species to change what instance again will create.

like image 104
Patrick Evans Avatar answered Oct 24 '22 11:10

Patrick Evans