ECMAScript 6 引入的 JavaScript 类(class)--类同java class

在 ECMAScript 6 引入的 JavaScript 类(class)是 JavaScript 现有的原型继承的语法糖。 类并不是 JavaScript 里加入的新的面向对象的继承模型。JavaScript 中的类只是能让我们用更简洁明了的语法创建对象及处理相关的继承。

定义类

类实际上是个“特殊的函数”,而且正如函数的定义方式有函数声明函数表达式两种一样,类的定义方式也有两种,分别是:类声明类表达式

类声明

类声明是定义类的一种方式,就像下面这样,使用 class 关键字后跟一个类名(这里是 Polygon),就可以定义一个类。

1 class Polygon {
2   constructor(height, width) {
3     this.height = height;
4     this.width = width;
5   }
6 }

变量提升

类声明和函数声明不同的一点是,函数声明存在变量提升现象,而类声明不会。也就是说,你必须先声明类,然后才能使用它,否则代码会抛出 ReferenceError 异常,像下面这样:

1 var p = new Polygon(); // ReferenceError
2
3 class Polygon {}

类表达式

类表达式是定义类的另外一种方式。在类表达式中,类名是可有可无的。如果定义了类名,则该类名只有在类体内部才能访问到。

 1 // 匿名的
 2 var Polygon = class {
 3   constructor(height, width) {
 4     this.height = height;
 5     this.width = width;
 6   }
 7 };
 8
 9 // 命名的
10 var Polygon = class Polygon {
11   constructor(height, width) {
12     this.height = height;
13     this.width = width;
14   }
15 };

注意: 类表达式和类声明一样也不会有提升的现象。

类体和方法定义

类的成员需要定义在一对花括号 {} 里,花括号里的代码和花括号本身组成了类体。类成员包括类构造器和类方法(包括静态方法和实例方法)。

严格模式

类体中的代码都强制在严格模式中执行。

构造器

构造器方法是一个特殊的类方法,其用于创建和初始化对象(用该类生成的)。一个类只能拥有一个名为constructor 的方法,否则会抛出 SyntaxError 异常。

在子类的构造器中可以使用 super 关键字调用父类的构造器。

原型方法

参见方法定义

 1 class Polygon {
 2   constructor(height, width) {
 3     this.height = height;
 4     this.width = width;
 5   }
 6
 7   get area() {
 8     return this.calcArea()
 9   }
10
11   calcArea() {
12     return this.height * this.width;
13   }
14 }
15 const square = new Polygon(10, 10);
16
17 // 100
18 console.log(square.area);

静态方法

static 关键字用来定义类的静态方法。静态方法是指那些不需要对类进行实例化,使用类名就可以直接访问的方法,需要注意的是静态方法不能被实例化的对象调用。静态方法经常用来作为工具函数。

 1 class Point {
 2     constructor(x, y) {
 3         this.x = x;
 4         this.y = y;
 5     }
 6
 7     static distance(a, b) {
 8         const dx = a.x - b.x;
 9         const dy = a.y - b.y;
10
11         return Math.sqrt(dx*dx + dy*dy);
12     }
13 }
14
15 const p1 = new Point(5, 5);
16 const p2 = new Point(10, 10);
17
18 console.log(Point.distance(p1, p2));

使用 extends 创建子类

extends 关键字可以用在类声明或者类表达式中来创建一个继承了某个类的子类。

 1 class Animal {
 2   constructor(name) {
 3     this.name = name;
 4   }
 5
 6   speak() {
 7     console.log(this.name + ‘ makes a noise.‘);
 8   }
 9 }
10
11 class Dog extends Animal {
12   speak() {
13     console.log(this.name + ‘ barks.‘);
14   }
15 }
16
17 var d = new Dog(‘Mitzie‘);
18 // ‘Mitzie barks.‘
19 d.speak();

同样也可以用于原有的原型继承的“类”:

 1 function Animal (name) {
 2   this.name = name;
 3 }
 4 Animal.prototype.speak = function () {
 5   console.log(this.name + ‘ makes a noise.‘);
 6 }
 7
 8 class Dog extends Animal {
 9   speak() {
10     super.speak();
11     console.log(this.name + ‘ barks.‘);
12   }
13 }
14
15 var d = new Dog(‘Mitzie‘);
16 d.speak();

需要注意的是类不能继承一般(非构造的)对象。如果你想要创建的类继承某个一般对象的话,你要使用 Object.setPrototypeOf()

 1 var Animal = {
 2   speak() {
 3     console.log(this.name + ‘ makes a noise.‘);
 4   }
 5 };
 6
 7 class Dog {
 8   constructor(name) {
 9     this.name = name;
10   }
11   speak() {
12     super.speak();
13     console.log(this.name + ‘ barks.‘);
14   }
15 }
16 Object.setPrototypeOf(Dog.prototype, Animal);
17
18 var d = new Dog(‘Mitzie‘);
19 d.speak();

Species

你可能想要数组类 MyArray 返回的是 Array 对象。这个 species 模式能让你重写默认的构造器。

例如,当使用像 map() 这样的方法来返回默认的构造器时,你想要这个方法返回父级的 Array 对象,而不是MyArray 对象。Symbol.species 能实现:

1 class MyArray extends Array {
2   // Overwrite species to the parent Array constructor
3   static get [Symbol.species]() { return Array; }
4 }
5 var a = new MyArray(1,2,3);
6 var mapped = a.map(x => x * x);
7
8 console.log(mapped instanceof MyArray); // false
9 console.log(mapped instanceof Array);   // true

使用 super 引用父类

super 关键字可以用来调用其父类的构造器或者类方法

class Cat {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ‘ makes a noise.‘);
  }
}

class Lion extends Cat {
  speak() {
    super.speak();
    console.log(this.name + ‘ roars.‘);
  }
}

Mix-ins

抽象子类或者 mix-ins 是类的模板。 一个 ECMAScript 类只能仅有一个父类,所以想要从工具类来多重继承的行为是不可能的。子类继承的只能是父类提供的功能性。

在 ECMAScript 里一个将父类作为输入且将其子类作为输出的函数可以用来实现 mix-ins:

1 var calculatorMixin = Base => class extends Base {
2   calc() { }
3 };
4
5 var randomizerMixin = Base => class extends Base {
6   randomize() { }
7 };

使用 mix-ins 的类可以像下面这样写:

1 class Foo { }
2 class Bar extends calculatorMixin(randomizerMixin(Foo)) { }


相关:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
时间: 2024-10-10 06:35:18

ECMAScript 6 引入的 JavaScript 类(class)--类同java class的相关文章

你需要知道的 JavaScript 类(class)的这些知识

作者: Dmitri Pavlutin译者:前端小智来源:dmitripavlutin 点赞再看,养成习惯 本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料.欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西. JavaScript 使用原型继承:每个对象都从原型对象继承属性和方法. 在Java或Swift等语言中使用的传统类作为创建对象的蓝图,在 JavaScript 中不

实际上ECMAScript中并没有对类的定义

首先,我们用一个经典例子来简单阐述一下ECMAScript中的继承机制. 在几何学上,实质上几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形.矩形和五边形都是多边形的一种,具有不同数量的边.正方形是矩形的一种,所有的边等长.这就构成了一种完美的继承关系.如下图: 在这个例子中,形状(Shape)是椭圆形(Ellipse)和多边形(Polygon)的基类(base class)(所有类都由它继承而来).椭圆具有一个属性 foci,说明椭圆具

javascript类继承

function extend(subClass, superClass) { var f = function() {}; f.prototype = superClass.prototype; subClass.prototype = new f(); subClass.superClass = superClass.prototype; } var parent = function (name, age) { this._name = name; this._age = age; };

一种JavaScript 类的设计模式

一种JavaScript 类的设计模式尽管前面介绍了如何定义一个类,如何初始化一个类的实例,但既可以在function定义的函数体中添加成员,又可以用prototype 定义类的成员,代码显的很混乱,和面向对象语言类的实现之间有着很大的区别.那么,如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式,并将它们对应到面向对象语言类的实现上.类的构造函数用来初始化一个实例,是每个类必不可少的一部分.在传统意义的面向对象中,类的构造函数的名称和类的名称一致,同时它们的定义方式和类成员的定义是类似

第九章:Javascript类和模块

(过年了,祝大家新年好!) 第6章详细介绍了javascript对象,每个javascript对象都是一个属性集合,相互之间没有任何联系.在javascript中也可以定义对象的类,让每个对象都共享某些属性,这种“共享”的特性是非常有用的.类的成员或实例都包含一些属性,用以存放它们的状态,其中有些属性定义了它们的行为(通常称为方法).这些行为通常是由类定义的,而且为所有实例所共享.例如,假如有一个名为complex的类用来表示复数,同时还定义了一些复数运算.一个complex实例应当包含复数的实

ExtJS教程(2)--- Javascript类和对象基础知识

Javascript中的类其实就是一个function 如下面定义一个Person类 //定义一个类 function Person(){ this.name = 'jaune'; this.age = 18; } //创建一个对象 var person1 = new Person(); console.log(person1); /* * 控制台打出以下内容 * Person {name: "jaune", age: 18} */ 上面是一个简单的定义类及创建类的方法 //定义一个带

JavaScript 与 ECMAScript的关系,JavaScript构成

引用w3school的描述: JavaScript 的核心 ECMAScript 描述了该语言的语法和基本对象: DOM 描述了处理网页内容的方法和接口: BOM 描述了与浏览器进行交互的方法和接口; Jvascript分为了三个部分,因此ECMAScript只是语法的核心,定义了如下规范: 语法 类型 语句 关键字 保留字 运算符 对象 ECMAScript的规范不仅只适用于Javascript,同样适用于其他语言,如ActionScript; Javascript的另外部分: 一:DOM(文

JavaScript学习总结(十三)——极简主义法编写JavaScript类

前两天在网上无意中发现了一篇使用极简主义法定义JavaScript类的文章,原文链接,这个所谓的"极简主义法"我还是第一次听说,是荷兰程序员Gabor de Mooij提出来的,这种方法不使用this和prototype,代码部署起来非常简单,这大概也是它被叫做"极简主义法"的原因.下面就介绍如何使用极简主义法完成JavaScript的封装和继承 1. 封装 首先,它也是用一个对象模拟"类".在这个类里面,定义一个构造函数createNew(),

JavaScript类和模块

类 在JavaScript中,类的实现是基于原型继承机制的.如果两个实例都从同一个原型对象上继承了属性,我们说它们是同一个类的实例. 构造函数 从某种意义上讲,定义构造函数即是定义类,所以构造函数名首字母要大写,而普通的函数都是首字母小写. // 构造函数,首字母大写 // 注意,这里并没有创建并返回一个对象,仅仅是初始化 function Range(from , to) { // 添加2个属性,这2个属性是不可继承的,每个对象都拥有唯一的属性 this.from = from; this.t