传统的构造函数的问题
1. 属性和原型方法定义分离,降低了可读性
2. 原型成员可以被枚举
3. 默认情况下,构造函数仍然可以被当作普通函数使用
类的特点
1. 类声明不会被提升,与 let 和 const 一样,存在暂时性死区
2. 类中的所有代码均在严格模式下执行
3. 类的所有方法都是不可枚举的
4. 类的所有方法都无法被当作构造函数使用
5. 类的构造器必须使用 new 来调用
普通构造函数
function Hexo(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Hexo.prototype.print = function () {
console.log(`【名字】:${this.name}`);
console.log(`【年龄】:${this.age}`);
console.log(`【性别】:${this.sex}`);
}
const hexo = new Hexo('张三', '10', '男')
console.log(hexo)
for (const prop in hexo) {
console.log(prop)
}
类的示例
class Hexo {
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
print() {
console.log(`【名字】:${this.name}`);
console.log(`【年龄】:${this.age}`);
console.log(`【性别】:${this.sex}`);
}
}
const hexo = new Hexo('张三', '10', '男')
console.log(hexo)
for (const prop in hexo) {
console.log(prop)
}
类的其他书写方式
可计算的成员名
const hexoName = 'hexoName';
const hexoAge = 'hexoAge';
const hexoSex = 'hexoSex'
class Hexo{
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
[hexoName](){
console.log(this.name)
}
[hexoAge](){
console.log(this.age)
}
[hexoSex](){
console.log(this.sex)
}
}
const hexo = new Hexo('张三','10','男')
hexo[hexoName]();
访问器属性
当其属性值有其限制时就可以使用访问器属性,es5中Object.defineProperty 可定义某个对象成员属性的读取和设置
使用getter和setter控制的属性,不在原型上
getter 无参数
setter 单参数
class Animal {
constructor(type, name, age, sex) {
this.type = type;
this.name = name;
this.age = age;
this.sex = sex;
}
//创建一个age属性,并给它加上getter,读取该属性时,会运行该函数
get age() {
return this._age + "岁";
}
//创建一个age属性,并给它加上setter,给该属性赋值时,会运行该函数
set age(age) {
if (typeof age !== "number") {
throw new TypeError("age property must be a number");
}
if (age < 0) {
age = 0;
}
else if (age > 1000) {
age = 1000;
}
this._age = age; // _age 下划线为系统保留属性,去掉会让程序误认为 this.age = age 这样不就是赋值吗,给age赋值不就会调用set age 这个方法吗
// 这样不就递归,最后会导致栈溢出
}
}
var a = new Animal("狗", "旺财", 3, "男");
静态成员 / 字段初始化器(ES7)
其区别
使用static的字段初始化,添加的是静态成员
没有使用static的字段初始化器,添加的成员位于对象上
箭头函数在字段初始化器位置上,指向当前对象
静态成员
构造函数本身的成员
何为静态成员看笔记类/包装类/静态属性与成员属性,说白啦就是静态成员只能自身调用,实例化后的不能调用
class hexo {
// es6 的写法
static type = '人';
static func (){
console.log('也可使定义静态方法')
}
constructor(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}
}
// 以前构造函数的写法
// hexo.type = 'ren';
const h = new hexo('张三','10','男')
字段初始化器(ES7)
class hexo {
// es7 使用字段初始化器的写法 与小面为未使用的一致,只是写法不一样
sex='男'
conSex(){
console.log(this.sex)
}
constructor(name, age) {
this.name = name;
this.age = age;
// es6的写法,未使用字段初始化器的写法
this.sex = '男';
}
}
const h = new hexo('张三','10');
类的表达式
匿名类
const A = class { //匿名类,类表达式
a = 1;
b = 2;
}
const a = new A();
console.log(a)