类不存在变量提升(hoist),这一点与 ES5 完全不同。
new Foo(); // ReferenceError
class Foo {}
与函数一样,类也可以使用表达式的形式定义。
const MyClass = class Me {
getClassName() {
return Me.name;
}
};
上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是
MyClass
而不是
Me
,
Me
只在 Class 的内部代码可用,指代当前类。
与 ES5 一样,实例的属性除非显式定义在其本身(即定义在
this
对象上),否则都是定义在原型上(即定义在
class
上)。
//定义类
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') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
上面代码中,
x
和
y
都是实例对象
point
自身的属性(因为定义在
this
变量上),所以
hasOwnProperty
方法返回
true
,而
toString
是原型对象的属性(因为定义在
Point
类上),所以
hasOwnProperty
方法返回
false
。这些都与 ES5 的行为保持一致。
私有方法是常见需求,但 ES6 不提供,只能通过变通方法模拟实现。
class Widget {
foo (baz) {
bar.call(this, baz);
}
// ...
}
function bar(baz) {
return this.snaf = baz;
}
还有一种方法是利用
Symbol
值的唯一性,将私有方法的名字命名为一个
Symbol
const bar = Symbol('bar');
const snaf = Symbol('snaf');
export default class myClass{
// 公有方法
foo(baz) {
this[bar](baz);
}
// 私有方法
[bar](baz) {
return this[snaf] = baz;
}
// ...
};
Class 的取值函数(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'