一、什么是类
使用 Object 创建对象时,我们无法区分不同类型的对象,也不方便批量创建对象。在 JS 中,我们可以通过类(class)来解决这个问题。类是对象模板,我们可以将对象中的属性和方法直接定义在类中。定义后,我们就可以通过类来创建对象。
语法格式如下:
class 类名{
}
类型 = class{
}
通过同一个类创建的对象,我们称为同类对象,可以使用 instanceof 来检查一个对象是否由某个类创建。如果某几个对象是由某个类所创建的,则我们称该对象是这个类的实例。
class Person{
}
Dog = class{
}
let p1 = new Person();
let p2 = new Person();
let d1 = new Dog();
console.log(p1);
console.log(d1);
console.log(p1 instanceof Person);
console.log(p1 instanceof Dog);
二、属性和方法
类是创建对象的模板,要创建对象第一件事就是定义类。
class Person{
/*
类的代码块默认就是严格模式
类的代码块是用来设置对象的属性
*/
// 实例属性,只能通过实例访问
name = 'Sakura';
age;
// 静态属性(类属性),只能通过类访问
static staticProperty = 'test静态属性';
// 方法
eat(){
// 实例方法中this就是当前实例
console.log(this.name + '吃饭了');
}
sleep = function(){
console.log(this.name + '睡觉了');
}
// 静态方法(类方法),通过类调用
static staticMethod(){
console.log('我是一个静态方法');
// 静态方法中this指向的是当前类
console.log(this);
}
}
let p1 = new Person();
// 调用实例属性
console.log(p1);
console.log(p1.name);
// 调用静态属性(类属性)
console.log(Person.staticProperty);
// 调用实例方法
p1.sleep();
p1.eat();
// 调用静态方法(类方法)
Person.staticMethod();
三、构造函数
当我们在类中直接指定实例属性的值时,意味着我们创建的所有对象的属性都是这个值。在类中,我们可以添加一个特殊的方法 constructor(),该方法我们称为 构造函数(构造方法)。构造方法会在我们调用类创建对象时执行,我们可以在构造函数中,为实例属性进行赋值。在构造函数中,this 表示当前所创建的对象。
class Person{
name;
age;
gender;
// 构造方法(构造函数),会在调用类创建对象时执行
constructor(name,age,gender){
// console.log('构造函数执行了')
// 可以在构造函数中,为实例属性进行赋值
// 在构造函数中, this表示当前所创建的对象。
this.name = name;
this.age = age;
this.gender = gender;
}
sleep(){
console.log(this.name + '睡觉了');
}
}
let p1 = new Person('Sakura',10,'女');
let p2 = new Person('Mikoto',14,'女');
console.log(p1);
console.log(p2);
四、旧类
早期的 JS 中,直接通过函数定义类。
- 一个函数如果直接调用 xxx(),那么这个函数就是一个普通函数
- 一个函数如果通过 new 调用 new xxx(),那么这个函数就是一个构造函数;
function 类名(参数1,参数2,...){
this.属性1 = 参数1;
this.属性2 = 参数2;
...
this.方法1 = function(参数列表){
方法体;
}
this.方法2 = function(参数列表){
方法体;
}
}
// 立即执行函数
var Person = (function(){
function Person(name,age){
// 添加属性
this.name = name;
this.age = age;
/*
// 添加方法
this.hello = () => {
console.log('My name is ' + this.name);
}
*/
}
// 向原型中添加属性(方法)
Person.prototype.hello = () => {
console.log('你好');
}
// 静态属性
Person.staticProperty = '静态属性';
// 静态方法
Person.staticMethod = function(){
console.log('静态方法');
}
return Person;
})();
var person = new Person('Sakura',10);
console.log(person);
person.hello();
console.log(Person.staticProperty);
Person.staticMethod();
var Animal = (function(){
function Animal(){
}
return Animal;
})();
var Cat = (function(){
function Cat(){
}
// 继承Animal
Cat.prototype = new Animal();
return Cat;
})();
var cat = new Cat();
console.log(cat);
console.log(cat instanceof Cat);
console.log(cat instanceof Animal);
五、new运算符
当使用 new 去调用一个函数时,这个函数将会作为构造函数调用。使用 new 调用函数时,将会发生这些事:
- 创建一个普通的 JS 对象(Object 对象 {}),为了方便,称其为新对象
- 将构造函数的 protoType 属性设置为新对象的原型
- 使用实参来执行构造函数,并且将新对象设置为函数中的 this
- 如果构造函数返回的是一个非原始值,则该值会作为 new 运算的返回值返回
- 如果构造函数返回值是一个原始值或没有返回值,则新的对象将会作为返回值