示例:

class A {
// 属性表达式
prop1 = 1;
// get方法
get value() {
console.log('Getting the current value!');
return this.prop1;
}
// set方法
set value(newValue) {
console.log('Setting the current value!');
this.prop1 = newValue;
}
// 箭头函数表达式
arrowFunc = (...args) => {
console.log(args);
}
// constructor
constructor(b = 2) {
this.prop2 = b;
}
// 普通函数表达式
Func() {
console.log("Func");
}
// 静态属性
static prop3 = 3;
// 静态普通函数
static staticFunc() {
console.log("staticFunc", this);
}
// 静态箭头函数
static staticArrowFunc = () => {
console.log("staticArrowFunc", this);
}
}
const a = new A(3);

使用babel编译成es5的代码,编译结果会生成几个内部函数:

// 类的调用检查,如果调用A不使用new,则会报错
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
// 定义原型上的普通函数、静态普通函数、get和set方法
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
// 定义属性到obj上,重新赋值使用defineProperty,第一次赋值直接添加属性
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}

类的编译结果:

// A是一个立即执行函数 返回结果是个函数 函数名就是类名
var A = /*#__PURE__*/ (function () {
// constructor
function A() {
// 转化constructor中的默认参数
var b =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
// 检查类是否使用new执行
_classCallCheck(this, A);
// 属性表达式定义到类实例上
_defineProperty(this, "prop1", 1);
// 箭头函数表达式定义到类实例上
_defineProperty(this, "arrowFunc", function () {
// 这个for循环是转换...args,遍历arguments,将每一项赋值给args对象
for (
var _len = arguments.length, args = new Array(_len), _key = 0;
_key < _len;
_key++
) {
args[_key] = arguments[_key];
}
console.log(args);
});
this.prop2 = b;
} _createClass(
A,
[
{// get和set方法
key: "value",
get:
function get() {
console.log("Getting the current value!");
return this.prop1;
},
set: function set(newValue) {
console.log("Setting the current value!");
this.prop1 = newValue;
}
},
{// 普通函数表达式
key: "Func",
value: function Func() {
console.log("Func");
}
}
],
[
{// 静态普通函数
key: "staticFunc",
value: function staticFunc() {
console.log("staticFunc", this);
}
}
]
); return A;
})();
// 静态属性定义到类上
_defineProperty(A, "prop3", 3);
// 静态箭头函数定义到类上
_defineProperty(A, "staticArrowFunc", function () {
console.log("staticArrowFunc", A);
}); var a = new A(3);

下图可描述整个编译结果:

需要注意的是:

  • 类原型上的方法、类的静态方法、类的get和set方法默认是不可枚举的
  • 类实例上的方法和属性、类的静态箭头函数是可枚举的

之后再出一章class继承的相关内容

从babel编译结果分析class的实现原理的更多相关文章

  1. KoaHub.js可借助 Babel 编译稳定运行在 Node.js 环境上

    koahubjs KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, A ...

  2. 使用babel编译es6

    起因:开发中慢慢的学习使用es6,但是JavaScript需要浏览器来解析,而不是所有浏览器都支持es6,所以为了兼容es6,需要第三方工具进行编译es6. 工具:node,gulp,gulp-bab ...

  3. React系列文章:Babel编译JSX生成代码

    上次我们总结了React代码构建后的Webpack模块组织关系,今天来介绍一下Babel编译JSX生成目标代码的一些规则,并且模拟整个生成的过程. 我们还是拿最简单的代码举例: import {gre ...

  4. 持续集成篇_08_Hudson持续集成服务器的使用(自动化编译、分析、打包、部署)

    持续集成篇_08_Hudson持续集成服务器的使用(自动化编译.分析.打包.部署) 1.创建任务 svn用户验证 验证通过 *****五颗*表示每分钟检查svn路径是否有变更,有变更就会重新构建,相当 ...

  5. webpack打包调试react并使用babel编译jsx配置方法

    http://lxj8749.iteye.com/blog/2287074 ********************************************** 安装webpack npm i ...

  6. es6 babel编译

    本文主要参照阮一峰的es6入门,为提高自己写了一份随笔. 原文地址请戳这里  ECMAScript 6 入门 ECMAScript 6是JavaScript语言的下一代标准.因为当前版本的ES6是在2 ...

  7. jrtplib源码分析 第一篇 jthread的编译与分析

    第一篇 jthread的编译与分析 jrtplib代码依赖库jthread,因此先从jthread开始jrtplib的学习.首先从以下链接下载jthread的源代码http://research.ed ...

  8. 编译调试 .NET Core 5.0 Preview 并分析 Span 的实现原理

    很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的

  9. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  10. ILSpy,DLL反编译工具,学习与了解原理的好帮手

    你是否一直苦于找到了好的dll却只知道怎么使用而不知道其原理. 你是否在使用一个dll的时候发现它在一些参数时报错了却没法解决. 你是否想成为一个优秀的.net开发,成为一个优秀的系统制造者. 那你需 ...

随机推荐

  1. idea提交时忽略.class、.iml文件和文件夹或目录的方法

    第一种方法 在Setings–> Editor --> File Types -->Ignore files and folders中添加需要忽略的文件和文件夹: .idea 忽略 ...

  2. ratel hook app

    目录 创建平头哥项目 创建一个基本的Android项目 手动创建一个平头哥项目(windows推荐) 通过模板的方式创建平头哥项目(windows不推荐) 插入第三方集成模块 RPC调用 RPC调用静 ...

  3. vue3 vite等笔记

    1.脚手架 vue-cli基于webpack封装,生态非常强大,可配置性也非常高,几乎能够满足前端工程化的所有要求.缺点就是配置复杂,甚至有公司有专门的webpack工程师专门做配置,另外就是webp ...

  4. Delphi线程中使用waitfor返回值

    使用waitfor的时候就不要再设置Freeonterminated属性了,否则会提示线程句柄错误.主要是里面使用了ExitThread方法,当线程方法执行完毕后会自动释放线程的.不过记得要重写Des ...

  5. 配置windows server多个用户同时使用一个账户远程服务器

    首先,需要服务器开启远程桌面连接: 右键点击"这台电脑"弹出菜单栏,选择"属性"   弹出系统窗口,点击"远程设置"   弹出系统属性窗口, ...

  6. C#之List、Queue、Stack使用EnsureCapacity方法预设数组大小

    简介 List.Queue 和 Stack 集合中的 EnsureCapacity方法预设数组大小. 为什么以及何时使用EnsureCapacity 方法 这里我们将首先了解为什么需要使用这种方法以及 ...

  7. 什么是spring框架

    一bai.概念:1. spring是开源的轻量级框架2 spring核心主要两部分:(1)aop:面向切面编程,扩展功能不是修改源代码实现(2)ioc:控制反转,- 比如有一个类,在类里面有方法(不是 ...

  8. <雪山飞狐><飞狐外传 >合辑剧情+随笔

    严格而言雪山飞狐与飞狐外传的剧情并不相关,前者写作与前,然后飞狐外传算是对雪山飞狐中形象并不饱满的胡斐作进一步补充描述,同时对二十余年前苗人凤与胡一刀之间故事的补充,以及众人叙述中的一些补充.因此虽然 ...

  9. sql文件导入错误,There was an error while executing a query. The query and the error message has been logged at: C:\U

    x.sql转储文件导入异常. 之前成功导入过,再次导入异常. 1修改my.ini文件,2修改sql文件编码.都不适用. 解决方法:新建数据库,再次导入成功.注意编码.

  10. AX2012 快速清空整个log表数据

    如果当一个log表的数据非常大的时又需要清理时,如果允许删除全部数据,在AX里,可以 将log表的TableType调整为[TempDB], 保存同步后再将TableType设置回[Regular]即 ...