JavaScript class 类

类是用于创建对象的模板。
我们使用 class 关键字来创建一个类,类体在一对大括号 {} 中,我们可以在大括号 {} 中定义类成员的位置,如方法或构造函数。

constructor构造方法

  • 构造方法在创建新对象时会自动执行,用于创建和初始化对象属性。
  • 如果不定义构造方法,JavaScript 会自动添加一个空的构造方法。
  • 可以返回函数的构造方法,可以用于判断变量属性
  • 一个类只能拥有一个名为“constructor”的特殊方法。如果类包含多个constructor的方法,则将抛出 一个SyntaxError
  • 一个构造函数可以使用 super 关键字来调用一个父类的构造函数。

创建

我们使用关键字 class 创建一个类,可以添加一个 constructor() 方法,然后添加任意数量的方法

class ClassName {
  constructor() { ... }
	//方法会在类的原型上
	method1(){...}
	method2(){...}
}

定义好类后,我们就可以使用 new 关键字来创建对象:

class Runoob {
  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
  age() {
    let date = new Date();
    return date.getFullYear() - this.year;
  }
}
 
let runoob = new Runoob("菜鸟教程", 2018);
document.getElementById("demo").innerHTML =
"菜鸟教程 " + runoob.age() + " 岁了。";

类表达式

  • 类表达式是定义类的另一种方法。类表达式可以命名或不命名。
  • 命名类表达式的名称是该类体的局部名称。
// 未命名/匿名类
let Runoob = class {
  constructor(name, url) {
    this.name = name;
    this.url = url;
  }
};
console.log(Runoob.name);// "Runoob"
 
// 命名类表达式
let Runoob = class Runoob2 {
	//Runoob2这个名字仅在类内部可见
  constructor(name, url) {
    this.name = name;
    this.url = url;
  }
};
console.log(Runoob.name);// "Runoob2"

//动态按需创建
function makeClass(phrase) {
  // 声明一个类并返回它
  return class {
    sayHi() {
      alert(phrase);
    }
  };
}
// 创建一个新的类
let User = makeClass("Hello");
new User().sayHi(); // Hello

声明提升

函数声明会提升,但是类声明不会提升

getters、setters

就像对象字面量,类包括 getters/setters,计算属性(computed properties)等。

  • getter 是一种获得属性值的方法,setter是一种设置属性值的方法
  • getter负责查询值,它不带任何参数,setter则负责设置键值,值是以参数的形式传递,在他的函数体中,一切的return都是无效的
  • get/set访问器不是对象的属性,而是属性的特性特性只有内部才用,因此在javaScript中不能直接访问他们,为了表示特性是内部值,用两队中括号括起来表示如[[Value]]
  • 注意:即使 getter 是一个方法,当你想获取属性值时也不要使用括号。
  • getter/setter 方法的名称不能与属性的名称相同,在本例中属名为 sitename。
    • 很多开发者在属性名称前使用下划线字符 _ 将 getter/setter 与实际属性分开
class User {
  constructor(name) {
    // 调用 setter
    this.name = name;
  }
  get name() {
    return this._name;
  }
  set name(value) {
    if (value.length < 4) {
      alert("Name is too short.");
      return;
    }
    this._name = value;
  }
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name is too short.

计算属性名称[…]

class User {
  ['say' + 'Hi']() {
    alert("Hello");
  }
}
new User().sayHi();

类字段

“类字段”是一种允许添加任何属性的语法。
类字段重要的不同之处在于,它们会在每个独立对象中被设好,而不是设在 User.prototype:

class User {
  name = "John";
}
let user = new User();
alert(user.name); // John
alert(User.prototype.name); // undefined

使用类字段绑定方法

确保方法中的this指向class对象
在浏览器环境中,它对于进行事件监听尤为有用。

class Button {
  constructor(value) {
    this.value = value;
  }
  click = () => {
    alert(this.value);
  }
}

let button = new Button("hello");
setTimeout(button.click, 1000); // hello

特性

  • 和普通函数不同,必须通过new调用
  • 类方法不可枚举
  • 类总是使用use strict
class Runoob {
  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
  age() {
    // date = new Date();  // 错误 该变量不可以使用
    let date = new Date(); // 正确 、
    return date.getFullYear() - this.year;
  }
}