探索 Class 底层原理
Posted jweboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了探索 Class 底层原理相关的知识,希望对你有一定的参考价值。
ECMAScript6
实现了 class
,实际上它是一个语法糖,但是它的出现能使 JS
编码更清晰,更接近 面向对象编程
。
实现原理
首先我们来看 ES6
中 class
的实现和 ES5
构造函数的实现,两者相比较不难看出 constructor
其实就是构造方法,指向 ES5
的构造函数,那么 class
本身指向的是构造函数,换言之底层依旧是构造函数。
ES6
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
static run() {
console.log("run");
}
say() {
console.log("hello!");
}
}
ES5
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function () {
console.log("hello!");
};
Person.run = function () {
console.log("run");
};
babel 编译分析
通过 babel
编译器将 ES6
代码 转换成 ES5
代码之后(代码转换可以试用 babel 官方在线工具),可得到这两个关键函数 _defineProperties
和 _createClass
,现在我们来一一解析说明。
...
var Person = /*#__PURE__*/ (function () {
"use strict";
function Person(name, age) {
_classCallCheck(this, Person);
this.name = name;
this.age = age;
}
_createClass(
Person,
[
{
key: "say",
value: function say() {
console.log("hello!");
},
},
],
[
{
key: "run",
value: function run() {
console.log("run");
},
},
]
);
return Person;
})();
\\_createClass
_createClass
函数主要用于配置构造函数或构造函数原型上的公有函数和静态方法,并返回构造函数本身。
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
\\_defineProperties
_defineProperties
函数主要用于声明公有函数和静态方法的描述符,并将其挂载到当前的构造函数或构造函数原型。它接收两个参数 target
() 和 props
。
target
指向当前的构造函数或构造函数原型props
数组类型,指向公有函数和静态方法
在遍历数组时,我们可以看到 enumerable
默认是 false
,也就是说 class
类上的内部属性默认是不可枚举的,不能使用 Object.keys
遍历,具体如下:
Object.keys(Person.prototype); // []
Object.keys(Person); // []
同时在遍历的时候还会判断当前描述符是否存在 value
值,如果存在就设置可写属性 writable
为 true
,反之就使用 get
和 set
属性。在遍历的末尾,通过 Object.defineProperty
将描述符配置到当前的构造函数或构造函数原型上,至此就是 class
的基本实现了。
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);
}
}
构造函数的区别
暂时性死区
class
不会声明提升,存在 暂时性死区
,构造函数的本质是函数,函数声明会有提升作用。
// 以上是关于探索 Class 底层原理的主要内容,如果未能解决你的问题,请参考以下文章