基础知识
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 Point {
constructor (x, y) {
this.x = x
this.y = y
}
toString () {
return '(' + this.x + ',' + this.y + ')'
}
}
所以 ES6 中的类,完全可以看作构造函数的另一种写法
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
上面代码就可以看出来,类的数据类型就是函数,类本身也就指向了构造函数。
使用的时候,也是直接对类使用 new 命令,跟构造函数的用法完全一致。
class Bar {
test() {
console.log('test')
}
}
var b = new Bar()
b.test() // 'test'
构造函数的 prototype 属性,在 ES6 的类上继续存在的。类的所有所发都式定在函数的 prototype 属性上面的。
class Point {
constructor () {
}
toString () {
}
toValue () {
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {}
}
在类的实例上面调用方法,其实就是调用原型上的方法
class B {}
let b = new B()
b.constructor === B.prototype.constructor
constructor 方法 constructor 方法式类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个空的 construct 方法会被默认添加。
class Point {}
// 等同于
class Point {
constructor() {}
}
取值函数 getter 和 存值函数 setter
class Myclass {
constructor() {
}
get prop() {
return 'getter'
}
set prop(value) {
console.log('setter' + value)
}
}
let inst = new Myclass()
inst.prop = 123
// setter 123
inst.prop
// getter
静态方法
类相当于实例的原型,所有类中定义的方法,都会被实例继承。如果一个方法前,加static关键字,就表示该方法不会被实例继承,而是直接通过类来调用。
class Foo {
static method() {
return 'hello world'
}
}
Foo.method() // 'hello world'
var foo = new Foo()
foo.method // TypeError
父类的静态方法可以被子类继承
class Foo {
static method() {
return 'hello world'
}
}
class Bar extends Foo {}
Bar.method() // 'hello world'
静态方法也是可以从 super 对象上调用的
class Foo {
static method() {
return 'hello world'
}
}
class Bar extends Foo {
static method() {
return super.method() + ',too'
}
}
Bar.method() // 'hello world,too'
class的继承
class 可以通过 extends 关键字实现继承,这比ES5通过原型链实现继承,要方便很多。
class Point {}
class ColorPoint extends Point {
constructor (x, y, color) {
super(x, y) // 调用父类的 constructor(x, y)
this.color = color
}
toString() {
return this.color + ' ' + super.toString()
// 调用父类的 toString()
}
}
Object.getPrototypeOf() Object.getPrototypeOf 方法可以用来从子类上获取父类
Object.getPrototypeOf(ColorPoint) === Point
可以使用这个方法判断 一个类是否继承了另一个类
类的 prototype 和 [[prto]]
class A {}
class B extends A {}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
产生上面代码的结果是因为,类的继承是按照下面方式实现的
class A {}
class B {}
// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype)
// B 继承 A 的静态属性
Object.setPrototypeOf(B, A)
// 对于 Object.setPrototypeOf 具体实现
Object.setPrototypeOf = function (obj, proto) {
obj.__proto__ = proto
return obj
}