自定义类型
在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);
声明类
- 使用
class
关键字,后面紧跟类名 - 在类中使用特殊的
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 { ... }
自定义类型和类
- 函数声明可以被提升,但是类声明不可以。类声明和let声明类似,也存在临时死区。
- 类声明的所有代码自动运行在严格模式下。
- 在类中,所有方法都是不可枚举的。
- 每个类都含有一个
[[constructor]]
内部方法。 - 只能通过
new
调用类中的构造函数,否则会报错。 - 在类中修改类名会报错。
根据以上关于类的描述,我们可以尝试使用自定义类型模拟 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;
}());
类和对象字面的相似之处
- 类也支持使用
get
/set
创建访问器属性 - 类方法和访问器属性支持可计算名称
- 在类中可以将任何方法定义成生成器
静态成员
使用 static
关键字创建类成员。静态成员只可以在类中访问,不可以在实例中访问。
class PersonCalss {
constructor(name){
this.name = name;
}
static create(name){
return new PersonCalss(name)
}
}
PersonCalss。create('phoeny');