代号巴别塔,将ES6的代码转化为ES5,用来适应低配置的浏览器,这里主要讲述概念,还有那个工具网站因为在国外一直打不开
ES6转化ES5转化网站:Babel · The compiler for next generation JavaScript (babeljs.io)
成功转化代码的配置:(因为网站会自动根据当前浏览器适配,如果你浏览器支持他可能就不给你适配了,所有需要调整一下,具体的后面的课程会讲)
(了解)ES6-babel工具对class类的转化
//转化之前
class Person{
constructor(name,age){
this.name = name
this.age = age
}
running(){}
eating(){}
static randomPerson(){}
}
class Student extends Person{
constructor(name,age,sno,score){
super(name,age)
this.sno = sno
this.score = score
}
studying(){}
}
"use strict";//严格模式
// 设置子类继承自父类
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
// 如果superClass既不是函数也不是null,则抛出异常
throw new TypeError("Super expression must either be null or a function");
}
// 创建subClass原型对象,继承自superClass原型,设置constructor属性指向subClass
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: { value: subClass, writable: true, configurable: true }
});
// 设置subClass原型的可写属性为false
Object.defineProperty(subClass, "prototype", { writable: false });
if (superClass) _setPrototypeOf(subClass, superClass);
}
// 设置对象的原型,相当于ES6的Object.setPrototypeOf或__proto__
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf
? Object.setPrototypeOf.bind()
: function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
// 创建“超类”的工具函数,用于在构造函数内调用super()
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
// 使用Reflect.construct来模拟使用new调用父类构造器
result = Reflect.construct(Super, arguments, NewTarget);
} else {
// 使用apply直接调用父类构造器
result = Super.apply(this, arguments);
}
// 返回结果,可能是对象或者undefined
return _possibleConstructorReturn(this, result);
};
}
// 根据构造函数的返回值确定返回的实例
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
// 如果构造函数返回一个对象或者函数,则使用它
return call;
} else if (call !== void 0) {
// 构造函数不能返回除undefined之外的非对象
throw new TypeError(
"Derived constructors may only return object or undefined"
);
}
// 如果构造函数返回的是this或undefined,则直接返回self
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError(
"this hasn't been initialised - super() hasn't been called"
);
}
return self;
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(
Reflect.construct(Boolean, [], function () { })
);
return true;
} catch (e) {
return false;
}
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf
? Object.getPrototypeOf.bind()
: function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _typeof(obj) {
"@babel/helpers - typeof";
return (
(_typeof =
"function" == typeof Symbol && "symbol" == typeof Symbol.iterator
? function (obj) {
return typeof obj;
}
: function (obj) {
return obj &&
"function" == typeof Symbol &&
obj.constructor === Symbol &&
obj !== Symbol.prototype
? "symbol"
: typeof obj;
}),
_typeof(obj)
);
}
function _classCallCheck(instance, Constructor) {
//如果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];//遍历所有的属性为其加上descript
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
//通过descriptor.key添加是因为,不希望我这些在默认情况下也会是不可枚举的
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {//protoProps,:实例方法,staticProps:静态方法
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);//封装起来的方法_defineProperties
Object.defineProperty(Constructor, "prototype", { writable: false });
return Constructor;
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return _typeof(key) === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
if (_typeof(input) !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (_typeof(res) !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
//tree shaking(摇树):如果你定义了但从来不使用,会进行删除。这个过程就叫做这个名词
//纯函数(__PURE__就是意味着提示这是一个纯函数):相同的输入一定产生相同的输出,并且不会产生副作用
var Person = /*#__PURE__*/ (function () {
//debugger,这是在后面会进行debugger的演示的
function Person(name, age) {
_classCallCheck(this, Person);//这一步只是做了更严谨的判断
this.name = name;
this.age = age;
}
_createClass(//转化为ES5后,我们的实例方法(原型链上的方法)跟静态方法static(类方法),_createClass会做出判断
Person,
[
{
key: "running",
value: function running() { }
},
{
key: "eating",
value: function eating() { }
}
],
[
{
key: "randomPerson",
value: function randomPerson() { }
}
]
);
return Person;
})();
var Student = /*#__PURE__*/ (function (_Person) {
_inherits(Student, _Person);
var _super = _createSuper(Student);
function Student(name, age, sno, score) {
var _this;
_classCallCheck(this, Student);
_this = _super.call(this, name, age);
_this.sno = sno;
_this.score = score;
return _this;
}
_createClass(Student, [
{
key: "studying",
value: function studying() { }
}
]);
return Student;
})(Person);
后面是debugger环节,不好通过语言描述,建议直接观看视频
(了解)ES6-babel工具对extends的转换
class Person{
constructor(name,age){
this.name = name
this.age = age
}
running(){}
eating(){}
static randomPerson(){}
}
class Student extends Person{
constructor(name,age,sno,score){
super(name,age)
this.sno = sno
this.score = score
}
//实例方法
studying(){}
//静态方法
static randomStudent(){}
}
var stu = new Student()
- 经过babel的转化(超级多)
"use strict";
function _inherits(subClass, superClass) {
//判断类型不是函数且不是null的时候,抛出异常
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
//边界的判断:superClass && superClass.prototype,superClass有值的时候才会执行后面原型的部分,防止内容是null会报错
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: { value: subClass, writable: true, configurable: true },
});
Object.defineProperty(subClass, "prototype", { writable: false });//设置subClass这个属性里面的原型里不可写,不能够继续赋值新值,因为改掉了值就无法实现继承了
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 _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {//当if (typeof Proxy === "function") return true的时候,就会执行这里面的内容
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {//否则就执行这个
result = Super.apply(this, arguments);//绑定了子类的this,然后将argument传递了进去
}
return _possibleConstructorReturn(this, result);
};
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError(
"Derived constructors may only return object or undefined"
);
}
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError(
"this hasn't been initialised - super() hasn't been called"
);
}
return self;
}
function _isNativeReflectConstruct() {
//判断当前的浏览器支不支持Reflect,这Proxy跟Reflect都是ES6的内容
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(
Reflect.construct(Boolean, [], function () { })
);
return true;
} catch (e) {
return false;
}
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf
? Object.getPrototypeOf.bind()//绑定到一个特定的对象上,这样可以让这个函数只能在这个特定对象上运行
: function _getPrototypeOf(o) {//判断你的浏览器支持哪种方式,是__proto__还是getPrototypeOf
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _typeof(obj) {
"@babel/helpers - typeof";
return (
(_typeof =
"function" == typeof Symbol && "symbol" == typeof Symbol.iterator
? function (obj) {
return typeof obj;
}
: function (obj) {
return obj &&
"function" == typeof Symbol &&
obj.constructor === Symbol &&
obj !== Symbol.prototype
? "symbol"
: typeof obj;
}),
_typeof(obj)
);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {//判断传入的内容是不是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, _toPropertyKey(descriptor.key), descriptor);
}
}
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 _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return _typeof(key) === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
if (_typeof(input) !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (_typeof(res) !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
var Person = /*#__PURE__*/ (function () {
function Person(name, age) {
_classCallCheck(this, Person);
this.name = name;
this.age = age;
}
_createClass(
Person,
[//实例方法
{
key: "running",
value: function running() { },
},
{
key: "eating",
value: function eating() { },
},
],
[//静态方法
{
key: "randomPerson",
value: function randomPerson() { },
},
]
);
return Person;
})();
//继承回顾
function inherit(SubType, SuperType) {
SubType.prototype = Object.create(SubType.prototype)
SubType.prototype.constructor = SubType
}
//核心代码
debugger
var Student = /*#__PURE__*/ (function (_Person) {
_inherits(Student, _Person);//这里的Student可以提前使用,因为下面的Student函数会作用域提升
var _super = _createSuper(Student);
function Student(name, age, sno, score) {
var _this;
_classCallCheck(this, Student);//检查这个this,让其不当作普通函数进行调用,而Student就是传入constructor形参的部分
_this = _super.call(this, name, age);//借用构造函数
_this.sno = sno;
_this.score = score;
return _this;
}
//实例方法
_createClass(
Student,
[
{
key: "studying",
value: function studying() { },
//静态方法
},
],
[
{
key: "randomStudent",
value: function randomStudent() { },
},
]
);
return Student;
})(Person);//这种()(Person)传递方式是为了避免函数产生闭包,对函数外的Person产生依赖,继续保持纯函数
var stu = new Student("小余",20,100,110)
(了解)ES6-babel工具源码的获取
只是在上面的基础上继续解释了一下,跳过