ES6 入门
class 的基本语法
简介
类的由来
通过构造函数生成实列对象
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);
通过class关键字定义类
class Point {// 构造方法constructor(x, y) {this.x = xthis.y = y}toString () {return `${this.x},${this.y}`}}
- ES6 的类 就是构造函数的另一种写法
class Point {...}// 类的数据类型也是函数typeof Point // function//Point === Point.prototype.constructor // true
- 类的所有方法都定义在类的prototype属性上
在类的实列调用方法,其实就是调用原型上的方法
class Point {constructor() {// ...}toString() {// ...}toValue() {// ...}}// 等同于Point.prototype = {constructor() {},toString() {},toValue() {},};
- 类的实列b的constructor方法就是类B原型的constructor方法
class B{}let b = new B()b.constructor === B.prototype.constructor
- prototype 对象的constructor属性,直接指向类本身
Point.prototype.constructor === Point // true
constructor 方法
constructor 方法是类的默认方法
通过new命令生成对象实列,自动调用该方法
一个类必须有constructor 方法,没有显示定义的话,一个空的constructor 方法会被默认添加
- constructor 方法默认返回实列对象
因此完全可以指定返回一个全新的对象
class Foo {constructor() {return Object.create(null);}}new Foo() instanceof Foo // false
- 类方法 必须使用new命令,不能当作普通方法调用 ```javascript class Foo { constructor() { return Object.create(null); } }
Foo() // TypeError: Class constructor Foo cannot be invoked without ‘new’
<a name="b7a03f8a"></a>### 类的实列-实列的属性除非显示的定义在其本身(即定义在this对象上),否则都是定义在原型上```javascript//定义类class Point {constructor(x, y) {this.x = x;this.y = y;}// 定义在了原型对象上toString() {return '(' + this.x + ', ' + this.y + ')';}}var point = new Point(2, 3);point.toString() // (2, 3)point.hasOwnProperty('x') // truepoint.hasOwnProperty('y') // truepoint.hasOwnProperty('toString') // falsepoint.__proto__.hasOwnProperty('toString') // true
- 所有的实列共享一个原型 ```javascript var p1 = new Point(2,3); var p2 = new Point(3,2);
// 他们的原型都是Point.pototype p1.proto === p2.proto
> 因为原型相同 在一个实列上为原型添加一个方法,其他实列都可以调用```javascriptvar p1 = new Point(2,3);var p2 = new Point(3,2);p1.__proto__.printName = function () { return 'Oops' };p1.printName() // "Oops"p2.printName() // "Oops"var p3 = new Point(4,2);p3.printName() // "Oops"
取值函数(getter) 和 存值函数 (setter)
- 对某个属性设置存值函数和取值函数 拦截该属性的存取行为
prop属性有对应的存值函数和取值函数,因此赋值和读取行为都被自定义了
class MyClass {constructor() {// ...}get prop() {return 'getter';}set prop(value) {console.log('setter: '+value);}}let inst = new MyClass();inst.prop = 123;// setter: 123inst.prop// 'getter'
Class 表达式
- 类也可以用表达式的形式定义
const MyClass = class Me {getClassName() {// Me 只能在内部使用 代指当前类// 在外部, 这个类只能用MyClass 引用return Me.name}}
- 采用Class 表达式 可以写出立即执行的class
```javascript
const person = new Class {
constructor(name) {
} sayName () {this.name = name
} }(‘张三’)console.log(this.name)
person.sayName() // 张三
<a name="85b97dce"></a>### 静态方法> 类相当于实列的原型,所有在类中定义的方法,都会被实列继承> 如果在一个方法前,加上staticu关键字,就表示该方法不会被实例继承,而是直接通过类来调用```javascriptclass Foo {static classMethod() {return 'hello';}}Foo.classMethod() // 'hello'// 只能通过类来调用 通过实例来调用会报错var foo = new Foo();foo.classMethod()// TypeError: foo.classMethod is not a function
- 如果静态方法包含this关键字 ,这个this指的是类,而不是实例
```javascript
class Foo {
static bar () {
// 此 this 指向类而不是实例
// 相当于FOO.baz
this.baz()
}
static baz () { console.log(‘hello’) } // 静态方法和非静态方法可以重名 baz () { console.log(‘world’) } }
Foo.bar()
-父类的静态方法可以被子类继承```javascriptclass Foo {static classMethod() {return 'hello';}}class Bar extends Foo {}Bar.classMethod() // 'hello'
静态方法也是可以从super对象上调用的
class Foo {static classMethod() {return 'hello';}}class Bar extends Foo {static classMethod() {return super.classMethod() + ', too';}}Bar.classMethod() // "hello, too"
