Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much ES6 classes differ from ES5 style?

I'm that kind of a person who needs to know everything in depth... So, I've been going through many taught subjects and I set my foot into depths of Prototype-inheritance.
I have a clear vision of how it works in ES5 (Every function has this special prototype property, which points to an object on which it is based on. This object has .constructor property, which points back to the function etc.).

So, now let's see ES5 example:

function Bunny(name) {
    this.name = name
}

Bunny.prototype.sayName = function() {
    console.log('Im',this.name)
}

This one is pretty clear: function Bunny gets argument name which's going to be assign to a new object.

Next line adds function to the function's prototype, which's going to return current name.

Let's see ES6 class now:

class Fox{
    constructor(name){
        this.name = name;
    }

    sayName() {
        console.log('Im', this.name)
    }
}

Same stuff here: Constructor here is like our Bunny function. But sayName in fox is not the same as sayName in Bunny.
Let's create the instances:

let bunny = new Bunny('Henry');
let fox = new Fox('Jerry');

And now, check their prototypes:

console.log(Object.getPrototypeOf(bunny))
console.log(Object.getPrototypeOf(fox))

What do we get?

//using repl.it - ES6
{ sayName: [Function] }
{}

Why is that?

I thought it might be because we set function sayName on Bunny's prototype directly. So I've changed it to this:

function Bunny(name) {
    this.name = name

    //Warning - Bad practice ahead! 
    this.sayName = function() {
        console.log('Im',this.name)
    }
}

Result:

//using repl.it - ES6
{}
{}

That would have sense, if not this:

console.log(bunny.hasOwnProperty('sayName'))
console.log(fox.hasOwnProperty('sayName'))

Which means, fox does not own sayName on him, either prototype shows it has it. Am I missing something here? Why They are different?

like image 422
krzysztof Avatar asked Nov 11 '16 14:11

krzysztof


People also ask

What is the major difference between ES6 class and ES5 function constructors?

ES6 class allows the developers to instantiate objects using the new operator. ES5 function constructors focus on how the objects are instantiated. They also ensure the developer that this keyword which is basically used inside the class only refers to the object that is being created by the developer.

What is the difference between the ES6 and ES5 standards in react?

ES6 provides high performance due to advanced features added to it and code optimization. ES6 has less community support than ES5 as it is a recent update on ES5 and not all browser supports it.

Are classes in ES5?

In the ES5 version, there are no classes; a function is used to make an object directly. However, the ES6 version uses the keyword class to define a class. The underlying concept is more or less the same. ES6 just cleans up the syntax.


1 Answers

In ES6 classes all methods are non-enumerable, so you when you log a prototype of an instance of an ES6 class, you get something that looks like an empty object.

See this example:

const obj = new (class {method() {}});

console.log(Object.getPrototypeOf(obj)); // {}
console.log(typeof Object.getPrototypeOf(obj).method); // function

In ES5 you define a method by assigning it to a property of the class prototype, which makes it enumerable. If you wanted to achieve the same effect as with ES6 classes, you could use Object.defineProperty() instead:

const TestClass = function TestClass() {};
Object.defineProperty(TestClass.prototype, 'method', {
  value: function() {},
  writable: true,
  enumerable: false,
  configurable: true,
});
const obj = new TestClass();

console.log(Object.getPrototypeOf(obj)); // {}
console.log(typeof Object.getPrototypeOf(obj).method); // function

And fox.hasOwnProperty('sayName') returns false because hasOwnProperty() checks only for own properties, and sayName is in the prototype chain. If you want to check for properties in the prototype chain too, you can use the in operator: 'sayName' in fox returns true.


See also Enumerability and ownership of properties on MDN.

like image 76
Michał Perłakowski Avatar answered Oct 17 '22 14:10

Michał Perłakowski