javascript ES 6 class 详解

来源:互联网 发布:苹果c语言编程软件 编辑:程序博客网 时间:2024/06/08 19:19

javascript ES 6 class 详解

Introduction

上篇文章大致介绍了一些ES6的特性,以及如何在低版本浏览器中使用它们。本文是对class的详解。
译自Axel Rauschmayer的Classes in ECMAScript 6
另外,如果只是想测试ES6,可以到这个网站。

Overview

借助class 我们可以写出这样的代码:

   class Point {        constructor(x, y) {            this.x = x;            this.y = y;        }        toString() {            return '(' + this.x + ', ' + this.y + ')';        }    }        class ColorPoint extends Point {        constructor(x, y, color) {            super(x, y);            this.color = color;        }        toString() {            return super.toString() + ' in ' + this.color;        }    }        let cp = new ColorPoint(25, 8, 'green');    cp.toString(); // '(25, 8) in green'        console.log(cp instanceof ColorPoint); // true    console.log(cp instanceof Point); // true

Base classes

我们可以定义如下的class:

    class Point {        constructor(x, y) {            this.x = x;            this.y = y;        }        toString() {            return '(' + this.x + ', ' + this.y + ')';        }    }

我们可以像使用ES5标准中的constructor一样实例化class

    > var p = new Point(25, 8);    > p.toString()    '(25, 8)'

实际上,class还是用function实现的,并没有为js创造一个全新的class体系。

    > typeof Point    'function'

但是,与function相比,它是不能直接调用的,也就是说必须得new出来

    > Point()    TypeError: Classes can’t be function-called

另外,它不会像function一样会被hoisted(原因是语义阶段无法解析到extends的内容)

    foo(); // works, because `foo` is hoisted    function foo() {}    new Foo(); // ReferenceError    class Foo {}
    function functionThatUsesBar() {        new Bar();    }        functionThatUsesBar(); // ReferenceError    class Bar {}    functionThatUsesBar(); // OK

与函数一样,class的定义表达式也有两种,声明形式、表达式形式。之前用的都是声明形式,以下是表达式式的:

    const MyClass = class Me {        getClassName() {            return Me.name;        }    };    let inst = new MyClass();    console.log(inst.getClassName()); // Me    console.log(Me.name); // ReferenceError: Me is not defined

Inside the body of a class definition

class定义体是只能包含方法,不能包含属性的(标准定义组织认为原型链中不应包含属性),属性被写在constructor中。以下是三种会用到的方法(constructor 、static method、 prototype method):

    class Foo {        constructor(prop) {            this.prop = prop;        }        static staticMethod() {            return 'classy';        }        prototypeMethod() {            return 'prototypical';        }    }    let foo = new Foo(123);

如下图([[Prototype]]代表着继承关系)当对象被new出来,拿的是Foo.prototype : Object分支,从而可以调prototype method

constructor,这个方法本身,代表了class

    > Foo === Foo.prototype.constructor    true

constructor有时被称为类构造器。相较于ES5,它可以调用父类的constructor(使用super())。

static methods。它们归属于类本身。

    > typeof Foo.staticMethod    'function'    > Foo.staticMethod()    'classy'

关于Getters and setters,它们的语法如下:

    class MyClass {        get prop() {            return 'getter';        }        set prop(value) {            console.log('setter: '+value);        }    }    > let inst = new MyClass();    > inst.prop = 123;    setter: 123    > inst.prop    'getter'

方法名是可以动态生成的

    class Foo() {        myMethod() {}    }        class Foo() {        ['my'+'Method']() {}    }        const m = 'myMethod';    class Foo() {        [m]() {}    }

增加了迭代器的支持,需要给方法前面加一个*

    class IterableArguments {        constructor(...args) {            this.args = args;        }        * [Symbol.iterator]() {            for (let arg of this.args) {                yield arg;            }        }    }        for (let x of new IterableArguments('hello', 'world')) {        console.log(x);    }        // Output:    // hello    // world

Subclassing

通过extends,我们可以继承其它实现constructor的函数或对象。需要注意一下,constructor与非constructor调用父类方法的途径是不同的。

    class Point {        constructor(x, y) {            this.x = x;            this.y = y;        }        toString() {            return '(' + this.x + ', ' + this.y + ')';        }    }        class ColorPoint extends Point {        constructor(x, y, color) {            super(x, y); // (A)            this.color = color;        }        toString() {            return super.toString() + ' in ' + this.color; // (B)        }    }    > let cp = new ColorPoint(25, 8, 'green');    > cp.toString()    '(25, 8) in green'        > cp instanceof ColorPoint    true    > cp instanceof Point    true

子类的原型就是它的父类

    > Object.getPrototypeOf(ColorPoint) === Point    true

所以,static method也被继承了

    class Foo {        static classMethod() {            return 'hello';        }    }        class Bar extends Foo {    }    Bar.classMethod(); // 'hello'

static方法也是支持调用父类的。

   class Foo {        static classMethod() {            return 'hello';        }    }        class Bar extends Foo {        static classMethod() {            return super.classMethod() + ', too';        }    }    Bar.classMethod(); // 'hello, too'

关于子类中使用构造器,需要注意的是,调用this之前,需要调用super()

    class Foo {}        class Bar extends Foo {        constructor(num) {            let tmp = num * 2; // OK            this.num = num; // ReferenceError            super();            this.num = num; // OK        }    }

constructors是可以被显示覆盖(override)的。

    class Foo {        constructor() {            return Object.create(null);        }    }    console.log(new Foo() instanceof Foo); // false

如果基类中不显示定义constructor,引擎会生成如下代码

    constructor() {}

对于子类

    constructor(...args) {        super(...args);    }

The details of classes

  • 类名不能为eval 或者 arguments,不能有重复的类名,constructor不支持getter,setter。
  • classes不能像函数一样调用。
  • 原型方法不能用作构造器:
    class C {        m() {}    }    new C.prototype.m(); // TypeError

The details of subclassing

ES 6中,子类的使用方法如下:

    class Point {        constructor(x, y) {            this.x = x;            this.y = y;        }        ···    }    class ColorPoint extends Point {        constructor(x, y, color) {            super(x, y);            this.color = color;        }        ···    }    let cp = new ColorPoint(25, 8, 'green');

原型链实现:

> const getProto = Object.getPrototypeOf.bind(Object);> getProto(Point) === Function.prototypetrue> getProto(function () {}) === Function.prototypetrue> getProto(Point.prototype) === Object.prototypetrue> getProto({}) === Object.prototypetrue
原文链接:http://www.cnblogs.com/E-WALKER/p/4796278.html
0 0
原创粉丝点击