JavaScript类与继承

作者: 长城_changcheng | 来源:发表于2018-03-10 03:02 被阅读13次

    一、ECMAScript 5标准中的类

    1、定义原型类
    /* 定义Calcula类 */
    
    var Calcula = function (x, y) {
        this.x = x;
        this.y = y;
    }
    Calcula.prototype = {
        add: function () {
            return this.x + this.y;
        },
        sub: function () {
            let x = this.x;
            let y = this.y;
            if (x > y) {
                return x - y;
            } else if (x < y) {
                return y - x;
            } else {
                return 0;
            }
        }
    };
    const calcula = new Calcula(100, 900);
    console.log(calcula.sub());
    

    2、原型类继承

    下面是一典型的关于原型继承的代码。

    /* 创建Foo原型类的Constructor函数 */
    var Foo = function (name) {
        this.name = name;
    }
    
    /* 为Foo原型类添加方法*/
    Foo.prototype = {
        myName: function () {
            console.log(this.name);
            return this.name;
        };
    };
    
    /* 创建Bar原型类的Constructor函数,并使之继承Foo类*/
    var Bar = function (name, label) {
        Foo.call(this, name);
        this.label = label;
    }
    
    /* 创建Bar类并使用Foo.prototype对象作为新创建的Bar类的prototyped对象,通俗的说就是使得新创建的Bar类继承于Foo类 */
    Bar.prototype = Object.create(Foo.prototype);
    
    /* 为Bar类添加myLabel方法*/
    Bar.prototype = {
        myLabel: function () {
            console.log(this.label);
            return this.label;
        };
    };
    
    const a = new Bar("编程语言JavaScript", "它是一门弱类型语言");
    a.myName();
    a.myLabel();
    

    3、静态类

    调用该类的静态方法不需要类的实例,该类的实例无法调用该类的任一静态方法,这也意味着类的静态方法内部的this指针是指向类本身的,而不是指向其实例。静态方法通常用于为一个应用程序创建工具函数。

    var Point = function (x, y) {
        this.x = x;
        this.y = y;
    
        this.distance = function (a, b) {
            const dx = a.x - b.x;
            const dy = a.y - b.y;
            return Math.hypot(dx, dy);
        };
    };
    
    var p1 = new Point(5, 5);
    var p2 = new Point(10, 10);
    
    console.log(p1.distance(10, 10));   // 因实例无法调用静态方法,所以浏览器会报错
    console.log(Point.distance(p1, p2));
    

    4、原型类扩展-类继承常规对象

    如果原型类要继承一个常规对象,则可以将对象设置为原型类的protypee对象。

    /* 实例1:类继承常规对象(JSON)*/
    var Animal = {
        hobby: ["篮球", "编程"],
        speak() {
            console.log(this.name + ' can speak English!');
            console.log(this.hobby);
        }
    };
    var Person = function (name) {
        this.name = name;
    };
    Person.prototype = Animal;
    var p = new Person("小明");
    p.speak();
    

    二、ECMAScript 6标准中的Class

    1、类

    /* 定义Greeter类,并添加Constructor构造器和greet方法  */
    class Greeter {
        constructor(message) {
            this.greeting = message;
        }
        greet() {
            return "你好," + this.greeting;
        }
    }
    let greeter = new Greeter("world");
    console.log(greeter.greet());
    

           声明了一个Greeter的类,它有3个成员:类的属性(greeting)、类的构造器(Constructor)、类的方法(greet)。

           在Greeter类的内部,this指针永远指向Greeter类自身。

           当我们使用new关键字实例化Class的时候,首先会执行自己的构造器中的方法。

    2、类继承(extends创建子类)

           extends关键字在类声明或类表达式中用于创建一个继承于另一个类的子类。

    class Animal { 
        constructor(name) {
            this.name = name;
        }
      
        speak() {
            console.log(this.name + ' makes a noise.');
        }
    }
    
    class Dog extends Animal {
    
        constructor() {
            super();
        }
    }
    
    var d = new Dog('Mitzie'); 
    d.speak();
    

           如果子类中存在构造函数,则需要在使用“this”之前首先调用super()。

    3、静态类

           static关键字用来定义一个类的一个静态方法,调用该类的静态方法不需要类的实例,该类的实例无法调用该类的任一静态方法,这也意味着类的静态方法内部的this指针是指向类本身的,而不是指向其实例。静态方法通常用于为一个应用程序创建工具函数。

    class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
    
        static distance(a, b) {
            const dx = a.x - b.x;
            const dy = a.y - b.y;
    
            return Math.hypot(dx, dy);
        }
    }
    
    const p1 = new Point(5, 5);
    const p2 = new Point(10, 10);
    
    console.log(p1.distance(10, 10));   // 因实例无法调用静态方法,所以浏览器会报错
    console.log(Point.distance(p1, p2));
    

    4、类扩展-类继承常规对象

           请注意,类不能扩展常规(不可构造/非构造的)对象。如果要继承常规对象,可以改用Object.setPrototypeOf():

    /* 实例1:类继承常规对象(JSON)*/
    const Animal = {
        hobby: ["篮球", "编程"],
        speak() {
            console.log(this.name + ' can speak English!');
            console.log(this.hobby);
        }
    };
    class Person {
        constructor(name) {
            this.name = name;
        }
    }
    // 以Animal对象作为Person类的原型对象
    Object.setPrototypeOf(Person.prototype, Animal);
    const d = new Person("小明");
    d.speak();
    
    /* 实例2:类继承常规对象(Array)*/
    const methods = [
        "正弦",
        "余弦",
        {
            name: "小明",
            hobby: [
                "编程", "LOL"
            ]
        }
    ];
    class Methods {
        constructor(name) {
            this.name = name;
        }
    }
    Object.setPrototypeOf(Methods.prototype, methods);
    const methodsItem = new Methods("Wangchangcheng");
    console.log(methodsItem[2]);
    

    相关文章

      网友评论

        本文标题:JavaScript类与继承

        本文链接:https://www.haomeiwen.com/subject/zekvfftx.html