前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Class降级

Class降级

原创
作者头像
剁椒鱼鳞
修改2023-06-26 18:29:55
1820
修改2023-06-26 18:29:55
举报
文章被收录于专栏:前端小学生前端小学生

下列ES6的代码降级为ES5

代码语言:javascript
复制
class Product {
    static count = 0;
    constructor(name, unitPrice, number) {
        this.name = name;
        this.unitPrice = unitPrice;
        this.number = number;
        Product.count++;
    }
    get totalPrice() { // ES6访问器,注意:会同时存在原型和实例上,而且不可枚举(控制台打印即灰色),不能被for-of、for-in等遍历到
        return this.number * this.unitPrice;
    }
    increase() { // 注意:不可枚举,且只能当作普通方法调用,不能通过new形式(new product.increase(),只能product.increase()来使用)来调用
        this.number++;
    }
}
const product = new Product();

分析: 1. class同let、const,有作用域死区,即先声明再使用,没有变量提升,包括方法等参数名也不能一样

2. class必须通过new来进行调用,否则就会报错

3. ES6访问器不可枚举,同时会存在在原型和实例上

4. ES6的方法不可枚举,同时只能当作普通方法调用,不能通过new形式来调用

5. ES6的继承是先将父类实例对象的属性和方法,添加到this上(所以必须先调用super()方法),然后再调用字累的构造函数修改this;ES5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上。class继承可以实现与安生构造函数的继承,而ES5的不可以。

6. class是在严格模式下执行的

代码语言:javascript
复制
var Product = (function (_Parent) {
    _Parent && _inherits(Product, _Parent);
    function Product(name, unitPrice, number) {
        if (Object.getPrototypeOf(this) !== Product.prototype) { // 当然也是可以绕开,如:var p = Product(); Product.call(p);
            // if (this.__protyo__ !== Product.prototype) { // ES不推荐使用__proto__
            // if (!new.target) { // ES6写法
            throw new TypeError('不能不使用new来调用');
        }
        this.name = name;
        this.unitPrice = unitPrice;
        this.number = number;
        Product.count++;
    }
    Object.defineProperty(Product.prototype, 'totalPrice', {
        get() {
            this.number * this.unitPrice;
        },
        enumerable: false,
    });
    Object.defineProperty(this, 'totalPrice', {
        get() {
            this.number * this.unitPrice;
        },
        enumerable: false,
    });
    Object.defineProperty(Product.prototype, 'increase', {
        value: function () {
            if (Object.getPrototypeOf(this) !== Product.prototype.increase.prototype) { // 当然也是可以绕开,如:var p = Product(); Product.call(p);
                /*
                new product.increase(); increase的this指向了increase的实例
                product.increase(); // increase的this指向了product
                通过以上,判断this指向是不是相同即可
                */
                throw new TypeError('不能不使用new来调用');
            }
            this.number++;
        },
        enumerable: false,
    });
    Product.count = 0;
    // Product.prototype.increase = function () { // 不能这么创建,不然increase会被枚举
    //     this.number++;
    // }
    return Product;
})();

function _inherits(subClass, superClass) {
    if (typeof superClass !== 'function' && superClass !== null) {
        throw new TypeError('superClass expression must either be null or a function, not ' + typeof superClass);
    }
    // 利用寄生继承继承父类原型
    superClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
        }
    })
    // 将子构造函数的__proto__指向父类构造函数,这里的setPrototypeOf方法和create类似,可以看出class继承同时存在两条继承链:子类构造函数的__proto__指向父类,子类原型的__proto__指向父类原型
    if (superClass) {
        Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com