一、简介
1、js中,生成实例对象的传统方式是通过构造函数。
function Point1(x,y){
this.x = x;
this.y = y;
}
Point.prototype.toStrings = function () {
return this.x+this.y;
}
var p = new Point1(1,2);
p.toStrings() // 3
2、ES6中通过Class关键字定义类
上面的代码通过es6的Class改写
// 通过es6改写Point
class Point {
//constructor 是构造方法,this代表实例对象
constructor (){
this.x = x;
this.y = y;
}
toStrings (){
return this.x+this.y
}
}
var p = new Point(1,2);
p.toStrings() // 3
类的数据类型就是函数,类本身就指向构造函数。
构造函数的prototype属性,在ES6的类上继续存在,实际上,类的所有方法都定义在类的prototype属性上面,在类的实例上调用方法,其实就是调用原型上的方法,类的内部所有定义的方法,都是不可枚举的,这一点与 ES5 的行为不一致
由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype上。Object.assign可以一次像类中添加多个方法
Object.assign(Point.prototype,{
toSum(){},
toValue(){}
})
二、constructor方法
constructir方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
class Point {}
// 等同于
class Point {
constructor (){}
}
三、类的实例对象
生成类的实例对象的写法:使用new命令,与es5一样,实例的属性除非显示的定义在其本身(及this对象上),否则都是定义在原型上(即class上),类的实例共享一个原型对象,这意味着,使用实例的__proto__属性改写原型,必须相当谨慎,不推荐使用,因为这会改变“类”的原始定义,影响到所有实例
//定义类
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
四、Class表达式
//这个类的名字是MyClass而不是Me,Me只在 Class 的内部代码可用,指代当前类
const MyClass = class me{
getClassName() {
return Me.name;
}
}
五、不存在变量提升
六、私有方法和私有属性
私有方法是常见需求,但是es6不提供,只能通过变通的方式模拟实现。
1、命名上加以区别,但是在类的外部还是可以访问该方法
class Widget {
// 公有方法
foo (baz) {
this._bar(baz);
}
// 私有方法
_bar(baz) {
return this.snaf = baz;
}
// ...
}
2、将私有方法移除模块
class Widget {
foo (baz) {
bar.call(this, baz);
}
// ...
}
function bar(baz) {
return this.snaf = baz;
}
3、利用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;
}
// ...
};
上面代码中,bar和snaf都是Symbol值,导致第三方无法获取到它们,因此达到了私有方法和私有属性的效果。
七、this的指向
八、类的静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function