What Is The Difference Between Prototype-based Class Syntax And Class Syntax In Javascript?
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 theirthis
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?"