类的写法
传统写法
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写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已)
class Point {
constructor(x, y) {
this.x = x;
this.y = y; 返回一个this实例对象
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
类的数据类型就是函数,类本身就指向构造函数
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
constructor
constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。constructor()方法默认返回实例对象(即this)
getter && setter
与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
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 classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()```
// TypeError: foo.classMethod is not a function
extends
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()
}
}
ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。
这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。
子类会继承父类的静态属性和方法,但实例不能继承类的静态属性和方法
由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
子类`B`的`__proto__`属性指向父类`A`,子类`B`的`prototype`属性的`__proto__`属性指向父类`A`的`prototype`属性
new 一个势力
function Person(name, age) {
this.name = name;
this.age = age;
}
let obj = {}; // 1
let result = Person.call(obj, 'lll'); // 2
obj.__proto__ = Person.prototype; // 3
if (typeof(result) == "object") // 4 如果Person返回一个对象, 则返回此对象 除外 返回新对象
p = result;
else
p = obj;
```