JavaScript 进阶营

JavaScript类与继承

2018-03-10  本文已影响13人  长城_changcheng

一、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]);
上一篇下一篇

猜你喜欢

热点阅读