JavaScript中的类与继承

一、ECMAScript 5标准中的类

1、定义原型类
/* 定义Calcula类 */
var Calcula = function (x, y) {
    this.x = x;
    this.y = y;
}
/* 此处使用了Object.defineProperties方法给Calcula.prototype添加方法,是
 * 为了保证类与ES6-Class编译后的类保持相同的特性,非必需不使用也可以
 */
Object.defineProperties(Calcula.prototype,  {
    add: {
        configurable: false,
        enumerable: false,
        value: function () {
            return this.x + this.y;
        },
        writable: false
    },
    sub: {
        configurable: false,
        enumerable: false,
        value: 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;
            }
        },
        writable: false
    }
});
const calcula = new Calcula(100, 900);
console.log(calcula.sub());

2、原型类继承

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

/* 创建Foo原型类的Constructor函数 */
var Foo = function (name) {
    this.name = name;
}

/* 为Foo原型类添加prototype方法*/
Foo.prototype = {
    myName: function () {
        console.log(this.name);
        return this.name;
    };
};

/* 创建Bar原型类的Constructor函数,并将this指针绑定到Foo类,使得Bar类的实例可以访问Foo类的属性和方法*/
var Bar = function (name, label) {
    Foo.call(this, name);
    this.label = label;
}

/* 创建Bar类并使用Foo.prototype对象作为新创建的Bar类的prototype对象 */
Bar.prototype = Object.create(Foo.prototype);

/* 为Bar类添加方法*/
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;
};

Point.distance = function (a, b) {
    const x = a - b;
    const y = a + b;
    return Math.hypot(x, y);
};

console.log(p1.distance(10, 10));   // 因实例无法调用静态方法,所以浏览器会报错
console.log(Point.distance(p1, p2));

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

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

/* 实例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标准中的类

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)。

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

2、类继承

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

class Animal { 
    constructor(name) {
        this.name = name;
    }
    eat() {
        console.log(this.name + '会汪汪叫');
    }
}

class Dog extends Animal {
    constructor() {
        super();
    }
}

var d = new Dog('狗A'); 
d.eat();

       如果子类中存在构造函数,则需要在使用“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("小明");
console.log(methodsItem[2]);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,114评论 0 13
  • The rule is simple: if a property or a method is not foun...
    __Liu__阅读 103评论 0 0
  • 人生应该是一个轮回。我感觉很多事情都是重走一遭。我认识某位女顾客很久了,总是保持若即若离的关系,像日光下的影子,有...
    2668e9ad2f35阅读 651评论 1 0
  • 秋风真的不易, 它为了消除塑料垃圾, 忽而将其高高抛起, 忽而又狠摔在地, 或者将其卷入水里,墙角,石头的缝隙, ...
    缘wxh阅读 327评论 11 21