ES6之对Class降级
如何将 ES6 降级到 ES5 ,这里有一个例子,结合之前的知识进行讲解:
//ES6降级ES5
// class Product {
// static count = 0;
// constructor(name, unitPrice, number) {
// this.name = name;
// this.unitPrice = unitPrice;
// this.number = number;
// Product.count++;
// }
// get totalPrice() {
// return this.unitPrice * this.number;
// }
// increase() {
// this.number++;
// }
// }
// console.log(new Product(),'before')
// 不能提前调用构造函数,会报错
var Product = (() => {
function Product(name, unitPrice, number) {
//官方不推荐使用this.__proto__
//防止不使用new调用
// console.log(this.__proto__,'this.__proto__')
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError("Class constructor Product cannot be invoked without 'new'")
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
//原型和实例里都需要get属性
Object.defineProperty(this, 'totalPrice', {
get() {
return this.unitPrice * this.number;
},
enumerable: false,//不可枚举
})
}
// 给原型上添加一个属性totalPrice,这样可以直接调用属性,后面描述了属性的行为
Object.defineProperty(Product.prototype, 'totalPrice', {
get() {
return this.unitPrice * this.number;
},
enumerable: false,//不可枚举
})
Product.count = 0;
//由于原型上的方法不可枚举,所以使用Object.defineProperty形式定义
Object.defineProperty(Product.prototype,'increase',{
enumerable: false,
value: function () {
//如果指向原型,说明通过new调用,规定不能通过new调用
if(Object.getPrototypeOf(this)===Product.prototype.increase.prototype){
throw new TypeError('increase is not a constructor')
// console.log(this,'普通')
}
console.log(this)
this.number++;
}
})
return Product;
})()
const p=new Product(1,2,3);
console.log(new p.increase(), 'after')
我们首先将 constructor,static ,increase 降级成构造函数的形式,static 是构造函数的静态方法,increase 是原型上的方法。
我们注意到如果在声明之前调用会报错,所以将整个内容包装在一个立即执行函数中,并返回一个 Product ,这样在之前调用返回的是 undefined 。
而且构造函数只能通过 new 调用,我们判断如果 this 没有指向原型,则一定是普通函数调用需要报错。这里不推荐使用 this._proto_ 的方式。
我们注意到还有一个 get 属性,我们使用 defineProperty 给原型添加一个 get 属性,后面可以直接执行属性的行为。并且需要增加不可枚举的属性。同时,在原型和实例中都需要写一次,因为两个地方都会出现。
最后对 increase 进行改造,由于也不可枚举所以也使用 defineProperty 的方式,同时当使用 new 调用时需要报错,可以通过判断 this 的指向是否指向函数的原型,如果指向原型,则一定是通过 new 来调用。