class Parent { static type = 'Parent'; #salary = 0; name = ''; static showType() { console.log(this.type) } #seeSalary() { console.log(this.#salary) } speakName() { this.#seeSalary() console.log(this.name) } } class Child extends Parent { constructor(name) { super(); this.name = name; } speakName() { super.speakName(); } }
{ "presets": [ "@babel/preset-env" ] }
npm install @babel/core @babel/cli @babel/preset-env --save-dev npx babel index.js -o dist.js
var _salary = new WeakMap(); var _seeSalary = new WeakSet(); var Parent = function () { function Parent() { _classPrivateMethodInitSpec(this, _seeSalary); _classPrivateFieldInitSpec(this, _salary, { writable: true, value: 0 }); } } function _seeSalary2() { console.log(_classPrivateFieldGet(this, _salary)); } function _classPrivateMethodInitSpec(obj, privateSet) { privateSet.add(obj); } function _classPrivateFieldInitSpec(obj, privateMap, value) { privateMap.set(obj, value); }
seeSalary
又不是seeSalary2
。首先要说的是,私有方法只能在类方法中调用,外部是没办法调用的,那么在方法中调用的时候会对调用seeSalary
进行拦截去执行seeSalary2
。weakMap
和weakSet
呢?Babel 是包含编译和polyfill两部分的。var Parent = function() { function Parent() { ... _defineProperty(this, "name", ''); } // 第一个参数是public方法,第二个参数是static方法 _createClass(Parent, [{ key: "speakName", value: function speakName() { _classPrivateMethodGet(this, _seeSalary, _seeSalary2).call(this); console.log(this.name); } }], [{ key: "showType", value: function showType() { console.log(this.type); } }]); return Parent; } _defineProperty(Parent, "type", 'Parent'); function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
prototype
身上;static的属性和方法都会定义在类自身上。var Child = function(_Parent2) { _inherits(Child, _Parent2); function Child(name) { var _this; _this = _callSuper(this, Child); _this.name = name; return _this; } _createClass(Child, [{ key: "speakName", value: function speakName() { _get(_getPrototypeOf(Child.prototype), "speakName", this).call(this); } }]); return Child; }(Parent); function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
prototype
指向了一个新对象,新对象的prototype
指向了父类的prototype
,且新对象的constructor
保持子类的constructor
不变且允许外部代码修改。然后将子类的prototype
拒绝被赋值为其他对象。最后将子类的__proto__
指向父类。prototype
直接指向父类的prototype
呢?这是因为在之前代码中给子类prototype
添加公开方法的时候避免影响父类。__proto__
指向父类呢?这是为了静态属性和方法也能让子类调用到父类的,前面也提到了静态的方法和属性都是挂载到类自身。__proto__
属性,通过该属性指向其他对象串联出原型链__proto__
还有prototype
,但是寻找原型链并不会经过prototype
,除非你是new了一个类,因为new关键字将类的prototype
作为实例__proto__
的值了。function P() {} P.prototype.x = 'x' function C() {} C.prototype = P.prototype console.log(C.x) // undefined
function P() {} P.prototype.x = 'x' P.x = 'xxx' function C() {} C.__proto__ = P; console.log(C.x) // xxx
以上就是详解babel是如何将class语法糖转换为es5的语法的详细内容,更多关于babel class转换为es5的资料请关注插件窝其它相关文章!