从babel编译结果分析class的实现原理
示例:
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的实现原理的更多相关文章
- KoaHub.js可借助 Babel 编译稳定运行在 Node.js 环境上
koahubjs KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, A ...
- 使用babel编译es6
起因:开发中慢慢的学习使用es6,但是JavaScript需要浏览器来解析,而不是所有浏览器都支持es6,所以为了兼容es6,需要第三方工具进行编译es6. 工具:node,gulp,gulp-bab ...
- React系列文章:Babel编译JSX生成代码
上次我们总结了React代码构建后的Webpack模块组织关系,今天来介绍一下Babel编译JSX生成目标代码的一些规则,并且模拟整个生成的过程. 我们还是拿最简单的代码举例: import {gre ...
- 持续集成篇_08_Hudson持续集成服务器的使用(自动化编译、分析、打包、部署)
持续集成篇_08_Hudson持续集成服务器的使用(自动化编译.分析.打包.部署) 1.创建任务 svn用户验证 验证通过 *****五颗*表示每分钟检查svn路径是否有变更,有变更就会重新构建,相当 ...
- webpack打包调试react并使用babel编译jsx配置方法
http://lxj8749.iteye.com/blog/2287074 ********************************************** 安装webpack npm i ...
- es6 babel编译
本文主要参照阮一峰的es6入门,为提高自己写了一份随笔. 原文地址请戳这里 ECMAScript 6 入门 ECMAScript 6是JavaScript语言的下一代标准.因为当前版本的ES6是在2 ...
- jrtplib源码分析 第一篇 jthread的编译与分析
第一篇 jthread的编译与分析 jrtplib代码依赖库jthread,因此先从jthread开始jrtplib的学习.首先从以下链接下载jthread的源代码http://research.ed ...
- 编译调试 .NET Core 5.0 Preview 并分析 Span 的实现原理
很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
- ILSpy,DLL反编译工具,学习与了解原理的好帮手
你是否一直苦于找到了好的dll却只知道怎么使用而不知道其原理. 你是否在使用一个dll的时候发现它在一些参数时报错了却没法解决. 你是否想成为一个优秀的.net开发,成为一个优秀的系统制造者. 那你需 ...
随机推荐
- el-pagination分页-自定义左右箭头样式
1,官方样式: 查了网上,有人说可以用slot插槽,但是试过之后,因为 不能插入多个 slot(没法定义名字做区分),所以导致左右按钮一样了.. 2,还有种方法: 利用 prev-text 和 n ...
- Windows 操作
一.基础命令 1. 盘符切换:D:: 2. 查看当前目录文件:dir: 3. 当前盘符内目录切换:cd path: 二.其他命令 1. netstat:查看网络端口状态 A. 查看某一端口信息:net ...
- 037_Clone Button
ResolutionTo do this first go to Setup | Customize | Accounts | Buttons and Links | New. Enter the f ...
- 鼠标JS
1.鼠标按住拖动 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- vue3 微信支付和支付宝支付 H5和微信内置浏览器
vue3微信支付和支付宝支付 // 判断是否为微信内置浏览器 let browser: any = navigator.userAgent.toLowerCase(); let isWechat: a ...
- Docker部署网心云-挣点电费
网心云 是CDN业务的一种,容器魔方 是网心云的容器安装产品,其安装也很简单. 1.启动容器--一行命令 docker run -d --name watchtower --restart alway ...
- Xcode常用&开发常用
p.p1 { margin: 0; font: 12px "Helvetica Neue" } p.p2 { margin: 0; font: 12px "Helveti ...
- 1903021126-申文骏 实验一 19信计java-Markdown排版
项目 内容 课程班级博客链接 19级信计班 作业要求链接 实验一 课程学习目标 大致学会Markdown排版 任务1:在博客园平台注册个人博客账号和加入班级博客 注册了博客园的个人账号,提交了博客申请 ...
- Leetcode——二分法bisect_left,bisect_right
!前提--列表有序 case 1 如果列表中没有元素x,那么bisect_left(ls, x)和bisec_right(ls, x)返回相同的值,该值是x在ls中"合适的插入点索引,使得数 ...
- c++学习 5 预处理
一 内存分区 内存的分区变量存储,一般可以分为以下五个区,它们分别是: 可读可写 堆区:使用malloc.calloc.realloc.free以及c++里面的new和delete去动态申请. ...