js ES5面向对象继承 模仿ES6

  因为本人是C#程序员的原因,开发过程中大部分时间都是面向对象开发的.但是对于javascript而言我好像更多的时候只是编写一些逻辑,而对于一些重复的功能而言,我就想要进行面向对象的组件化开发.虽然基于jqurey或原生js都封装过一些组件,但是总觉的代码并不是呢么的优美.面向对象的方式并不严谨.所以关于如何在javascript ES5版本下的面向对象开发,在我的脑海里面是一直想有一个完美的编写方式的.近两天查看了es6的class关键字创建类的方式.然后就想通过es5的编写方式来模仿es6进行类的封装.(当然,自己有时候也绝的这么做很蠢,别人提供好的方式为什么不用.但是心里还是有点小执念,想要搞清楚这个东西到底是什么个结构.)

  下面是我通过es6的方式创建的类和子类,然后在控制面板中创建出的对象结构.

class ES6_Class {
    name = "";
    #Job = "aa";
    constructor(...attr) {
        this.name = attr[0];
        var age = attr[1];
        Object.defineProperty(this, "age", {
            "enumerable": true,
            "get": function() {
                console.log("getter age");
                return age;
            },
            "set": function(val) {
                age = val;
            }
        })
    }
    sayHello() {
        console.log(`My name is ${this.name},I'm ${this.age} years old,I'm a ${sex}`);
    }
    static sayHi() {
        console.log(`hello`);

    }
}
class ES6_Child extends ES6_Class {
    constructor(...attr) {
        super(...attr);
    }

}
console.log("es6", new ES6_Class("Tom", 25));
console.log("es6c", new ES6_Child("Jim", 4));

下面是控制台中的输出

   中间的不同在于,es6c(子类对象)中的__proto__属性指向的类是有构造函数的,而这个构造是自己,这其实就相当于在原来的对象链上面修改了父级的__proto__而已.所以我就模拟着写了一个es5的写法

function ES5_Class(...attr) {
    this.name = attr[0];
    var age = attr[1];
    Object.defineProperty(this, "age", {
        "enumerable": true,
        "get": function() {
            console.log("getter age");
            return age;
        },
        "set": function(val) {
            age = val;
        }
    })
}
Object.defineProperties(ES5_Class.prototype, {
    "sayHello": {
        value: function() {
            console.log(`My name is ${this.name},I'm ${this.age} years old,I'm a ${sex}`);
        }
    }
})

function ES5_Child(...attr) {
    ES5_Class.apply(this, attr);
}
Function.prototype.extends = function(fnclass) {
    if (typeof fnclass == "function") {
        this.prototype.__proto__ = fnclass.prototype;
    }
}
ES5_Child.extends(ES5_Class)

console.log("es5", new ES5_Class("张三", 27));
console.log("es5c", new ES5_Child("李四", 5));

得出的控制台结果是一模一样的.

 这种写法在写的时候一定要注意,在es6中,类的方法是属于源对象(__proto__)的,并且要注意的是这些方法都是不可枚举的,所以建议使用 Object.defineProperties 的方式,在class.prototype上添加方法.

原文地址:https://www.cnblogs.com/flybeijing/p/flybeijing.html