In this article, we will focus on how private attributes are implemented in Babel and typescript. For details, see Ruan Yifong’s introduction to ES6

Before reading this article, you can read my previous posts on class from Babel (top) and class from Babel (bottom).

Sample files

The following code evolved from this example

class Foo {
  #name = 'zhangsan';
  age = 17;

  getName() {
    return this.#name;
  }
  get #x() {
    return this.#name;
  }

  set #x(value) {
    this.#name = value; }}Copy the code

babel

function _classPrivateFieldSet(receiver, privateMap, value) {
  var descriptor = privateMap.get(receiver);
  if(! descriptor) {throw new TypeError('attempted to set private field on non-instance');
  }
  if (descriptor.set) {
    descriptor.set.call(receiver, value);
  } else {
    if(! descriptor.writable) {throw new TypeError('attempted to set read only private field');
    }
    descriptor.value = value;
  }
  return value;
}

function _classPrivateFieldGet(receiver, privateMap) {
  var descriptor = privateMap.get(receiver);
  if(! descriptor) {throw new TypeError('attempted to get private field on non-instance');
  }
  if (descriptor.get) {
    return descriptor.get.call(receiver);
  }
  return descriptor.value;
}

var _name = new WeakMap(a);var _x = new WeakMap(a);var Foo = /*#__PURE__*/ (function () {
  function Foo() {
    _classCallCheck(this, Foo);

    _x.set(this, {
      get: _get_x,
      set: _set_x,
    });

    _name.set(this, {
      writable: true.value: 'zhangsan'}); _defineProperty(this.'age'.17);
  }

  _createClass(Foo, [
    {
      key: 'getName'.value: function getName() {
        return _classPrivateFieldGet(this, _name); }},]);returnFoo; }) ();var _get_x = function _get_x() {
  return _classPrivateFieldGet(this, _name);
};

var _set_x = function _set_x(value) {
  _classPrivateFieldSet(this, _name, value);
};
Copy the code

To keep things simple, I’ve cut out unnecessary code, and here’s the Babel execution order

  1. First of all by_classCallCheckMethod to check whether thenewCall, not throw an error directly
  2. throughnew WeakMapTo store private properties
  3. through_definePropertyTo set instance properties
  4. through_createClassTo set methods and static methods

So it can be concluded that Babel’s private property method is implemented through WeakMap

function _classPrivateFieldGet(receiver, privateMap) {
  var descriptor = privateMap.get(receiver);
  if(! descriptor) {throw new TypeError('attempted to get private field on non-instance');
  }
  if (descriptor.get) {
    return descriptor.get.call(receiver);
  }
  return descriptor.value;
}
Copy the code

A few extra judgments are made in the above method, one by one

  1. performprivateMap.get

The reason for the judgment is that this can be lost, for example through deconstruction

const f = new Foo();
const { getName } = f;
getName();
Copy the code
  1. Descriptor. The get judgment

    Because private attributes can be in the form of get and set

The _classPrivateFieldSet method is similar to the get process and will not be explained.

typescript

var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if(! privateMap.has(receiver)) {throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if(! privateMap.has(receiver)) {throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var _name;
class Foo {
    constructor() {
        _name.set(this.'zhangsan');
        this.age = 17;
    }
    getName() {
        return this.;
    }
    get () { return __classPrivateFieldGet(this, _name); }
    set (value) {
        __classPrivateFieldSet(this, _name, value);
    }
}
_name = new WeakMap(a);Copy the code

We’ll compile the code directly into ES2015 and we’ll look at how private properties are implemented in TS, but the class degradation method is degraded to a function so we’ll skip it.

Set, __classPrivateFieldGet and __classPrivateFieldSet from these three codes, we can draw the conclusion that TS is also implemented by WeakMap.

The implementation is much the same as with Babel, which reads and sets this and variable names

The last

The above analysis ends here, if there is any error welcome to point out, if it is helpful to you welcome star.