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
- First of all by
_classCallCheck
Method to check whether thenew
Call, not throw an error directly - through
new WeakMap
To store private properties - through
_defineProperty
To set instance properties - through
_createClass
To 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
- perform
privateMap.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
-
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.