本文实例讲述了 ES6 新特性之类 (Class) 和继承 (Extends) 相关概念与用法。分享给大家供大家参考,具体如下:
一、类(Class)
1. 基本语法
JavaScript 语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子
- function Point(x, y) {
- this.x = x;
- this.y = y;
- }
- Point.prototype.toString = function () {
- return '(' + this.x + ', ' + this.y + ')';
- };
- var p = new Point(1, 2);
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的 "类" 改写,就是下面这样。
- //定义类
- class Point {
- constructor(x, y) { //constructor 构造方法
- this.x = x;
- this.y = y;
- }
- toString() {
- return '(' + this.x + ', ' + this.y + ')';
- }
- }
- var p = new Point(1, 2);
构造函数的 prototype 属性,在 ES6 的 "类" 上面继续存在。事实上,类的所有方法都还是定义在类的 prototype 属性上面。
2.constructor 方法
constructor 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加。
二、继承(Extends)
Class 之间可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
- class ColorPoint extends Point {
- constructor(x, y, color) {
- super(x, y); // 调用父类的constructor(x, y)
- this.color = color;
- }
- toString() {
- return this.color + ' ' + super.toString(); // 调用父类的toString()
- }
- }
上面代码中,constructor 方法和 toString 方法之中,都出现了 super 关键字,它在这里表示父类的构造函数,用来新建父类的 this 对象。
子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工。如果不调用 super 方法,子类就得不到 this 对象。
三、原生构造函数继承
原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。以前,这些原生构造函数是无法继承的。
- Boolean()
- Number()
- String()
- Array()
- Date()
- Function()
- RegExp()
- Error()
- Object()
ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象 this,然后再用子类的构造函数修饰 this,使得父类的所有行为都可以继承。下面是一个继承 Array 的例子。
- class MyArray extends Array {
- constructor(...args) {
- super(...args);
- }
- }
- var arr = new MyArray();
- arr[0] = 12;
- arr.length // 1
- arr.length = 0;
- arr[0] // undefined
上面代码定义了一个 MyArray 类,继承了 Array 构造函数,因此就可以从 MyArray 生成数组的实例。这意味着,ES6 可以自定义原生数据结构(比如 Array、String 等)的子类,这是 ES5 无法做到的。
四、Class 的 Generator 方法
如果某个方法之前加上星号(*),就表示该方法是一个 Generator 函数。
- class Foo {
- constructor(...args) {
- this.args = args;
- }
- * [Symbol.iterator]() {
- for (let arg of this.args) {
- yield arg;
- }
- }
- }
- for (let x of new Foo('hello', 'world')) {
- console.log(x);
- }
- // hello
- // world
上面代码中,Foo 类的 Symbol.iterator 方法前有一个星号,表示该方法是一个 Generator 函数。Symbol.iterator 方法返回一个 Foo 类的默认遍历器,for...of 循环会自动调用这个遍历器。
五、Class 的静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为 "静态方法"。
- class Foo {
- static classMethod() {
- return 'hello';
- }
- }
- Foo.classMethod() // 'hello'
- var foo = new Foo();
- foo.classMethod()
- // TypeError: foo.classMethod is not a function
上面代码中,Foo 类的 classMethod 方法前有 static 关键字,表明该方法是一个静态方法,可以直接在 Foo 类上调用(Foo.classMethod()),而不是在 Foo 类的实例上调用。如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。
父类的静态方法,可以被子类继承。
- class Foo {
- static classMethod() {
- return 'hello';
- }
- }
- class Bar extends Foo {
- }
- Bar.classMethod(); // 'hello'
上面代码中,父类 Foo 有一个静态方法,子类 Bar 可以调用这个方法。
更多关于 JavaScript 相关内容感兴趣的读者可查看本站专题:《ECMAScript6(ES6) 入门教程》、《JavaScript 数组操作技巧总结》、《JavaScript 字符与字符串操作技巧总结》、《JavaScript 数据结构与算法技巧总结》、《JavaScript 错误与调试技巧总结》及《JavaScript 数学运算用法总结》
希望本文所述对大家 JavaScript 程序设计有所帮助。
来源: http://www.jb51.net/article/114567.htm