This is the 17th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

2. Classes on ES6 are Babel compiled

2.1 build a

The ES6 code is:

class Person {
  constructor(name) {
    this.name = name; }}Copy the code

Babel compiles to:

"use strict";

function _classCallCheck(instance, Constructor) {
  if(! (instanceinstanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function"); }}var Person = function Person(name) {
  _classCallCheck(this, Person);

  this.name = name;
};
Copy the code

The _classCallCheck function checks to see if Person is called with new. As we said above, the class must be called with new or it will report an error.

When we call Person with new, we construct a new object and bind it to this in the call to Person().

When called with var person = person (), this points to window, so instance instanceof Constructor will be false, consistent with ES6.

2.2 compile two

The ES6 code is:

class Person {
  // Instance properties
  foo = 'foo';
  
  // Static properties
  static bar = 'bar';

  constructor(name) {
    this.name = name; }}Copy the code

Babel compiles to:

'use strict';

function _classCallCheck(instance, Constructor) {
  if(! (instanceinstanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function"); }}var Person = function Person(name) {
  _classCallCheck(this, Person);

  this.foo = 'foo';

  this.name = name;
};

Person.bar = 'bar';
Copy the code

2.3 build three

The ES6 code is:

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

  sayHello() {
    return 'hello, I am ' + this.name;
  }

  static onlySayHello() {
    return 'hello'
  }

  get name() {
    return 'kevin';
  }

  set name(newName) {
    console.log('new name is: ' + newName)
  }
}
Copy the code

The code for ES5 should be:

function Person(name) {
  this.name = name;
}

Person.prototype =  {
  sayHello: function () {
    return 'hello, I am ' + this.name;
  },
  get name() {
    return 'kevin';
  },
  set name(newName) {
    console.log('new name is: ' + newName)
  }
}

Person.onlySayHello = function () {
  return 'hello'
};
Copy the code

Babel compiles to:

'use strict';

var _createClass = function() {
  function defineProperties(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); }}return function(Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    returnConstructor; }; } ();function _classCallCheck(instance, Constructor) {
  if(! (instanceinstanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function"); }}var Person = function() {
  function Person(name) {
    _classCallCheck(this, Person);

    this.name = name;
  }

  _createClass(Person, [{
    key: 'sayHello'.value: function sayHello() {
      return 'hello, I am ' + this.name; }}, {key: 'name'.get: function get() {
      return 'kevin';
    },
    set: function set(newName) {
      console.log('new name is: '+ newName); }}], [{key: 'onlySayHello'.value: function onlySayHello() {
      return 'hello'; }}]);returnPerson; } ();Copy the code

We can see that Babel generates a _createClass helper function that takes three arguments:

  • The first is the constructor, which in this case is Person
  • The second is an array of functions to add to the prototype
  • The third is the array of functions to add to the constructor itself, that is, all functions that add the static keyword.

This function adds methods from an array of functions to the constructor or prototype of the constructor, and returns the constructor.

In it, a defineProperties helper function is generated to add properties using the object.defineProperty method.

The default enumerable is false, and the additional information is true, as mentioned above, to prevent methods such as object.keys () from traversing it. And then it’s a getter and a setter by judging whether value exists. If there is a value, then add the value and writable attributes to the descriptor. If there is no, then use the get and set attributes to the descriptor.