深入理解ES6-9.类(1)

60 阅读2分钟

自定义类型

在ES5中,使用自定义类型来模拟一个类:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
     console.log(this.name);
}
var person = new Person('nico', 30);

声明类

  1. 使用 class 关键字,后面紧跟类名
  2. 在类中使用特殊的 constructor 方法名来定义构造函数。
class PersonCalss {
    constructor(name){
        this.name = name;
    }
    sayName(){
        console.log(this.name);
    }
}

let person = new PersonCalss('phoeny');
person.sayName();

类仅仅是自定义函数的语法糖。 当我们使用 typeof PersonCalss 时,会得到结果为 function。直接定于在类中的方法相当于在原型上定义的,sayName 方法像相当于 PersonCalss.prototype.sayName

同样可以使用 类表达式 的写法:

let PersonCalss = class { ... }

自定义类型和类

  1. 函数声明可以被提升,但是类声明不可以。类声明和let声明类似,也存在临时死区。
  2. 类声明的所有代码自动运行在严格模式下。
  3. 在类中,所有方法都是不可枚举的。
  4. 每个类都含有一个[[constructor]]内部方法。
  5. 只能通过 new 调用类中的构造函数,否则会报错。
  6. 在类中修改类名会报错。

根据以上关于类的描述,我们可以尝试使用自定义类型模拟 PersonClass 这个类。

// 不希望外部能访问到类内部的东西,所以一开始用自执行函数全部包裹起来
let PersonType = (function(){         // let:1
    'use strict';                     // use strict:2
    const PersonType = function(name) {         // 默认带[[constructor]]:4 / const:6
        if(typeof new.target === 'undefined'){   // new.target:5
            throw new Error('必须用new调用')
        }
        this.name = name;
    }
    Object.defineProperty(PersonType.prototype,'sayName',{
        value: function () {
            console.log(this.name);
        },
        enumerable: false,           // enumerable: false:3
        writable: true,
        configurable: true
    })
    return PersonType;
}());

类和对象字面的相似之处

  1. 类也支持使用 get / set 创建访问器属性
  2. 类方法和访问器属性支持可计算名称
  3. 在类中可以将任何方法定义成生成器

静态成员

使用 static 关键字创建类成员。静态成员只可以在类中访问,不可以在实例中访问。

class PersonCalss {
    constructor(name){
        this.name = name;
    }
    static create(name){
      return new PersonCalss(name)
    }
}
PersonCalsscreate('phoeny');