mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-28 21:32:20 +00:00
edit class
This commit is contained in:
parent
6129931efc
commit
eb5b1f07a9
@ -1,8 +1,6 @@
|
|||||||
# Class和Module
|
# Class和Module
|
||||||
|
|
||||||
## Class
|
## Class基本语法
|
||||||
|
|
||||||
### 基本语法
|
|
||||||
|
|
||||||
**(1)概述**
|
**(1)概述**
|
||||||
|
|
||||||
@ -11,12 +9,12 @@ ES5通过构造函数,定义并生成新对象。下面是一个例子。
|
|||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
function Point(x,y){
|
function Point(x,y){
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point.prototype.toString = function () {
|
Point.prototype.toString = function () {
|
||||||
return '('+this.x+', '+this.y+')';
|
return '('+this.x+', '+this.y+')';
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -109,7 +107,7 @@ point.toString() // (2, 3)
|
|||||||
point.hasOwnProperty('x') // true
|
point.hasOwnProperty('x') // true
|
||||||
point.hasOwnProperty('y') // true
|
point.hasOwnProperty('y') // true
|
||||||
point.hasOwnProperty('toString') // false
|
point.hasOwnProperty('toString') // false
|
||||||
point.__proto__.hasOwnProperty('toString') // false
|
point.__proto__.hasOwnProperty('toString') // true
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -125,9 +123,9 @@ p1.__proto__ === p2.__proto__
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,p1和p2都是Point的实例,它们的原型都是Point,所以\__proto__属性是相等的。
|
上面代码中,p1和p2都是Point的实例,它们的原型都是Point,所以\_\_proto\_\_属性是相等的。
|
||||||
|
|
||||||
这也意味着,可以通过\__proto__属性为Class添加方法。
|
这也意味着,可以通过\_\_proto\_\_属性为Class添加方法。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
@ -139,7 +137,7 @@ p1.__proto__.printName = function () { return 'Oops' };
|
|||||||
p1.printName() // "Oops"
|
p1.printName() // "Oops"
|
||||||
p2.printName() // "Oops"
|
p2.printName() // "Oops"
|
||||||
|
|
||||||
var p3 = new Point(4,2);
|
var p3 = new Point(4,2);
|
||||||
p3.printName() // "Oops"
|
p3.printName() // "Oops"
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -210,8 +208,8 @@ class Foo {}
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
{
|
{
|
||||||
let Foo = class {};
|
let Foo = class {};
|
||||||
class Bar extends Foo {
|
class Bar extends Foo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,9 +222,9 @@ class Foo {}
|
|||||||
|
|
||||||
类和模块的内部,默认就是严格模式,所以不需要使用`use strict`指定运行模式。考虑到未来所有的代码,其实都是运行在模块之中,所以ES6实际上把整个语言升级到了严格模式。
|
类和模块的内部,默认就是严格模式,所以不需要使用`use strict`指定运行模式。考虑到未来所有的代码,其实都是运行在模块之中,所以ES6实际上把整个语言升级到了严格模式。
|
||||||
|
|
||||||
### Class的继承
|
## Class的继承
|
||||||
|
|
||||||
**(1)基本用法**
|
### 基本用法
|
||||||
|
|
||||||
Class之间可以通过extends关键字,实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
|
Class之间可以通过extends关键字,实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
|
||||||
|
|
||||||
@ -248,14 +246,14 @@ class ColorPoint extends Point {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
return this.color+' '+super(); // 等同于parent.toString()
|
return this.color + ' ' + super.toString(); // 等同于parent.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,constructor方法和toString方法之中,都出现了super关键字,它指代父类的同名方法。在constructor方法内,super指代父类的constructor方法;在toString方法内,super指代父类的toString方法。
|
上面代码中,constructor方法和toString方法之中,都出现了super关键字,它指代父类的实例(即父类的this对象)。
|
||||||
|
|
||||||
子类必须在constructor方法中调用super方法,否则新建实例时会报错。
|
子类必须在constructor方法中调用super方法,否则新建实例时会报错。
|
||||||
|
|
||||||
@ -267,7 +265,7 @@ class ColorPoint extends Foo {
|
|||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let cp = new ColorPoint(); // ReferenceError
|
let cp = new ColorPoint(); // ReferenceError
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -282,7 +280,7 @@ constructor(...args) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
另一个需要注意的地方是,只有调用super方法之后,才可以使用this关键字,否则会报错。
|
另一个需要注意的地方是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为没有调用父类的构造函数,就无法子类实例的构建。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
@ -292,7 +290,7 @@ class Point {
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColorPoint extends Point {
|
class ColorPoint extends Point {
|
||||||
constructor(x, y, color) {
|
constructor(x, y, color) {
|
||||||
this.color = color; // ReferenceError
|
this.color = color; // ReferenceError
|
||||||
@ -303,7 +301,7 @@ class ColorPoint extends Point {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,子类的constructor方法没有调用super方法之前,就使用this关键字,结果报错,而放在super方法之后就是正确的。
|
上面代码中,子类的constructor方法没有调用super之前,就使用this关键字,结果报错,而放在super方法之后就是正确的。
|
||||||
|
|
||||||
下面是生成子类实例的代码。
|
下面是生成子类实例的代码。
|
||||||
|
|
||||||
@ -318,7 +316,7 @@ cp instanceof Point // true
|
|||||||
|
|
||||||
上面代码中,实例对象cp同时是ColorPoint和Point两个类的实例,这与ES5的行为完全一致。
|
上面代码中,实例对象cp同时是ColorPoint和Point两个类的实例,这与ES5的行为完全一致。
|
||||||
|
|
||||||
**(2)prototype属性**
|
### prototype属性
|
||||||
|
|
||||||
Class作为构造函数的升级,也有自己的prototype属性,其规则与ES5构造函数的prototype属性一致。
|
Class作为构造函数的升级,也有自己的prototype属性,其规则与ES5构造函数的prototype属性一致。
|
||||||
|
|
||||||
@ -346,7 +344,7 @@ C.prototype === Object
|
|||||||
|
|
||||||
上面代码中,子类的prototype属性都指向父类。如果一个类是基类(即不存在任何继承),那么它的原型指向`Function.prototype`。
|
上面代码中,子类的prototype属性都指向父类。如果一个类是基类(即不存在任何继承),那么它的原型指向`Function.prototype`。
|
||||||
|
|
||||||
**(3)Object.getPrototypeOf方法**
|
### Object.getPrototypeOf()
|
||||||
|
|
||||||
Object.getPrototypeOf方法可以用来从子类上获取父类。
|
Object.getPrototypeOf方法可以用来从子类上获取父类。
|
||||||
|
|
||||||
@ -357,9 +355,9 @@ Object.getPrototypeOf(ColorPoint) === Point
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**(4)\__proto\__属性**
|
### \_\_proto\_\_属性
|
||||||
|
|
||||||
父类和子类的\__proto\__属性,指向是不一样的。
|
父类和子类的\_\_proto\_\_属性,指向是不一样的。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
@ -371,12 +369,12 @@ p2.__proto__.__proto__ === p1.__proto__ // true
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
通过子类的\__proto\__属性,可以修改父类。
|
通过子类的\_\_proto\_\_属性,可以修改父类。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
p2.__proto__.__proto__.printName = function () {
|
p2.__proto__.__proto__.printName = function () {
|
||||||
console.log('Ha');
|
console.log('Ha');
|
||||||
};
|
};
|
||||||
|
|
||||||
p1.printName() // "Ha"
|
p1.printName() // "Ha"
|
||||||
@ -385,15 +383,15 @@ p1.printName() // "Ha"
|
|||||||
|
|
||||||
上面代码在ColorPoint的实例p2上向Point类添加方法,结果影响到了Point的实例p1。
|
上面代码在ColorPoint的实例p2上向Point类添加方法,结果影响到了Point的实例p1。
|
||||||
|
|
||||||
**(5)构造函数的继承**
|
### 构造函数的继承
|
||||||
|
|
||||||
下面是一个继承原生的Array构造函数的例子。
|
下面是一个继承原生的Array构造函数的例子。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
class MyArray extends Array {
|
class MyArray extends Array {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
super(...args);
|
super(...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,14 +406,14 @@ arr[1] = 12;
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
class MyError extends Error {
|
class MyError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MyError('Something happened!');
|
throw new MyError('Something happened!');
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 取值函数getter和存值函数setter
|
## class的取值函数(getter)和存值函数(setter)
|
||||||
|
|
||||||
与ES5一样,在Class内部可以使用get和set关键字,对某个属性设置存值函数和取值函数。
|
与ES5一样,在Class内部可以使用get和set关键字,对某个属性设置存值函数和取值函数。
|
||||||
|
|
||||||
@ -442,7 +440,7 @@ inst.prop
|
|||||||
|
|
||||||
上面代码中,prop属性有对应的存值函数和取值函数,因此赋值和读取行为都被自定义了。
|
上面代码中,prop属性有对应的存值函数和取值函数,因此赋值和读取行为都被自定义了。
|
||||||
|
|
||||||
### Generator方法
|
## Class的Generator方法
|
||||||
|
|
||||||
如果某个方法之前加上星号(*),就表示该方法是一个Generator函数。
|
如果某个方法之前加上星号(*),就表示该方法是一个Generator函数。
|
||||||
|
|
||||||
@ -458,7 +456,7 @@ class Foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let x of new Foo('hello', 'world')) {
|
for (let x of new Foo('hello', 'world')) {
|
||||||
console.log(x);
|
console.log(x);
|
||||||
}
|
}
|
||||||
@ -469,7 +467,7 @@ for (let x of new Foo('hello', 'world')) {
|
|||||||
|
|
||||||
上面代码中,Foo类的Symbol.iterator方法前有一个星号,表示该方法是一个Generator函数。Symbol.iterator方法返回一个Foo类的默认遍历器,for...of循环会自动调用这个遍历器。
|
上面代码中,Foo类的Symbol.iterator方法前有一个星号,表示该方法是一个Generator函数。Symbol.iterator方法返回一个Foo类的默认遍历器,for...of循环会自动调用这个遍历器。
|
||||||
|
|
||||||
### 静态方法
|
## Class的静态方法
|
||||||
|
|
||||||
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
|
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
|
||||||
|
|
||||||
@ -500,7 +498,7 @@ class Foo {
|
|||||||
return 'hello';
|
return 'hello';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar extends Foo {
|
class Bar extends Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user