Skip to content Skip to sidebar Skip to footer

What Is The Difference Between Prototype-based Class Syntax And Class Syntax In Javascript?

Are these interchangeable syntaxes to create a JS class? I'm used to the class syntax but don't understand the differences between them exactly. function User(name) { this.name

Solution 1:

The main differences between classes and constructor functions are:

  • Classes can’t be called without new, but functions intended as constructors can (and their this will be wrong)

    'use strict';
    
    functionFoo() {
        console.log(this);
    }
    
    classBar {
        constructor() {
            console.log(this);
        }
    }
    
    Foo();
    Bar();
  • Classes can extend more types than constructors can (like functions and arrays)

    'use strict';
    
    functionFoo(body) {
        Function.call(this, body);
    }
    
    Object.setPrototypeOf(Foo, Function);
    Foo.prototype = Object.create(Function.prototype);
    
    classBarextendsFunction {}
    
    (newBar('console.log(1)'))();
    (newFoo('console.log(1)'))();
  • Classes’ prototypes are their parents (they inherit static properties); writers of constructor functions usually don’t bother with this

  • Non-classes can’t extend classes (because they can’t call the parent constructor – see the first point)

    'use strict';
    
    classBarextendsFunction {}
    
    functionFoo() {
        Bar.call(this);
    }
    
    Object.setPrototypeOf(Foo, Bar);
    Foo.prototype = Object.create(Bar.prototype);
    
    voidnewFoo();

Classes are also scoped like let/const (block scope, temporal dead zone, not redeclareable) rather than like var (function scope, hoisted) or like function declarations (it’s complicated).

In your example, an additional difference is that sayHi is defined by assigning to a new property instead of with e.g. Object.defineProperty, so the property’s properties differ from those in the class example in that sayHi is enumerable in the former but not the latter.

functionUserA(name) {
    this.name = name;
}

UserA.prototype.sayHi = function () {
    alert(this.name);
};

classUserB {
    constructor(name) {
        this.name = name;
    }

    sayHi() {
        alert(this.name);
    }
}

let a = [];
let b = [];

for (let key innewUserA()) a.push(key);
for (let key innewUserB()) b.push(key);

console.log(a, b);

Solution 2:

From MDN:

JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

You can use a tool like the Babel REPL to see how the ES6, class-based code you have above is then transpiled into ES5, prototype-based code:

ES6 Class

classUser {

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

 sayHi() {
   alert(this.name);
 }

}

let user = newUser("John");
user.sayHi();

Transpiled to ES5

"use strict";

var _createClass = function () { functiondefineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value"in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } returnfunction (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); returnConstructor; }; }();

function_classCallCheck(instance, Constructor) { if (!(instance instanceofConstructor)) { thrownewTypeError("Cannot call a class as a function"); } }

varUser = function () {
  functionUser(name) {
    _classCallCheck(this, User);

    this.name = name;
  }

  _createClass(User, [{
    key: "sayHi",
    value: functionsayHi() {
      alert(this.name);
    }
  }]);

  returnUser;
}();

var user = newUser("John");
user.sayHi();

All ES6+ functionality will be able to be transpiled into ES5-- it is all, effectively, syntactic sugar. All "new features" can still be achieved in ES5. This is called, I believe, the "One JavaScript" doctrine.

Post a Comment for "What Is The Difference Between Prototype-based Class Syntax And Class Syntax In Javascript?"