詳解babel是如何將class語(yǔ)法糖轉(zhuǎn)換為es5的語(yǔ)法
準(zhǔn)備工作
- 在目錄下創(chuàng)建兩個(gè)文件,分別是index.js和.babelrc
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
編譯后私有變量和方法怎么存儲(chǔ)?
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);
}
- 總結(jié)這部分代碼:私有變量會(huì)存儲(chǔ)在weakMap中,鍵是對(duì)象,值是變量值;私有方法存儲(chǔ)在weakSet中,鍵是對(duì)象。對(duì)于方法存儲(chǔ)了對(duì)象還不夠,執(zhí)行方法是需要函數(shù)體的,函數(shù)體定義在外部。
- 問(wèn)題是,我調(diào)用的是
seeSalary又不是seeSalary2。首先要說(shuō)的是,私有方法只能在類方法中調(diào)用,外部是沒(méi)辦法調(diào)用的,那么在方法中調(diào)用的時(shí)候會(huì)對(duì)調(diào)用seeSalary進(jìn)行攔截去執(zhí)行seeSalary2。 - 還有一個(gè)問(wèn)題,調(diào)用babel轉(zhuǎn)換為es5的語(yǔ)法,怎么還有
weakMap和weakSet呢?Babel 是包含編譯和polyfill兩部分的。
編譯后靜態(tài)或公開變量和方法怎么存儲(chǔ)?
var Parent = function() {
function Parent() {
...
_defineProperty(this, "name", '');
}
// 第一個(gè)參數(shù)是public方法,第二個(gè)參數(shù)是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;
}
- 總結(jié)這部分代碼:public的屬性會(huì)定義在實(shí)例自身上,public的方法會(huì)定義在構(gòu)造器的
prototype身上;static的屬性和方法都會(huì)定義在類自身上。
那么繼承是怎么實(shí)現(xiàn)的?
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));
}
- 總結(jié)這部分代碼:繼承是通過(guò)修改子類的
prototype指向了一個(gè)新對(duì)象,新對(duì)象的prototype指向了父類的prototype,且新對(duì)象的constructor保持子類的constructor不變且允許外部代碼修改。然后將子類的prototype拒絕被賦值為其他對(duì)象。最后將子類的__proto__指向父類。 - 有個(gè)問(wèn)題,為什么要?jiǎng)?chuàng)建一個(gè)新對(duì)象而不是讓子類的
prototype直接指向父類的prototype呢?這是因?yàn)樵谥按a中給子類prototype添加公開方法的時(shí)候避免影響父類。 - 還有一個(gè)問(wèn)題,為什么需要
__proto__指向父類呢?這是為了靜態(tài)屬性和方法也能讓子類調(diào)用到父類的,前面也提到了靜態(tài)的方法和屬性都是掛載到類自身。
拓展:原型鏈
- 每個(gè)對(duì)象(數(shù)組、函數(shù)等)都有
__proto__屬性,通過(guò)該屬性指向其他對(duì)象串聯(lián)出原型鏈 - 函數(shù)不僅僅有
__proto__還有prototype,但是尋找原型鏈并不會(huì)經(jīng)過(guò)prototype,除非你是new了一個(gè)類,因?yàn)閚ew關(guān)鍵字將類的prototype作為實(shí)例__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語(yǔ)法糖轉(zhuǎn)換為es5的語(yǔ)法的詳細(xì)內(nèi)容,更多關(guān)于babel class轉(zhuǎn)換為es5的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
TypeScript?使用?Tuple?Union?聲明函數(shù)重載
這篇文章主要介紹了TypeScript?使用?Tuple?Union?聲明函數(shù)重載,TypeScript 中為函數(shù)添加多個(gè)簽名后,依然需要添加相應(yīng)的代碼來(lái)判斷并從不同的簽名參數(shù)列表中獲取對(duì)應(yīng)的參數(shù),下文就來(lái)探索方法和技巧吧2022-04-04
js 數(shù)組 find,some,filter,reduce區(qū)別詳解
區(qū)分清楚Array中filter、find、some、reduce這幾個(gè)方法的區(qū)別,根據(jù)它們的使用場(chǎng)景更好的應(yīng)用在日常編碼中。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
小程序?qū)崿F(xiàn)頁(yè)面多級(jí)來(lái)回切換的示例代碼
這篇文章主要為大家詳細(xì)介紹了小程序如何頁(yè)面多級(jí)來(lái)回切換支持滑動(dòng)和點(diǎn)擊操作,文中的實(shí)現(xiàn)步驟講解詳細(xì),快跟隨小編一起動(dòng)手嘗試一下吧2022-07-07
JavaScript對(duì)象轉(zhuǎn)數(shù)組的三種方法實(shí)現(xiàn)
本文介紹了在JavaScript中將對(duì)象轉(zhuǎn)換為數(shù)組的三種實(shí)用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-09-09
javascript動(dòng)畫系列之模擬滾動(dòng)條
本文主要介紹了js動(dòng)畫模擬滾動(dòng)條的實(shí)現(xiàn)原理以及分享了通過(guò)滾動(dòng)條實(shí)現(xiàn)的幾個(gè)應(yīng)用的實(shí)例代碼:1.通過(guò)移動(dòng)滾動(dòng)條來(lái)實(shí)現(xiàn)數(shù)字的加減;2.通過(guò)拖動(dòng)滾動(dòng)條來(lái)實(shí)現(xiàn)元素尺寸的變化,以改變?cè)貙挾葹槔?3.通過(guò)拖動(dòng)滾動(dòng)條來(lái)實(shí)現(xiàn)內(nèi)容滾。需要的朋友一起來(lái)看下吧2016-12-12
javascript+css實(shí)現(xiàn)單擊顏色褪去效果
javascript+css實(shí)現(xiàn)單擊顏色褪去效果...2007-08-08
JavaScript中實(shí)現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實(shí)例
這篇文章主要介紹了JavaScript中實(shí)現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實(shí)例,本文用2種方法實(shí)現(xiàn)了類似PHP的打亂數(shù)組函數(shù)shuffle函數(shù),需要的朋友可以參考下2014-10-10

