class是什么
在ES6中,class关键字提供了一种更简洁、更易读的语法来定义对象的构造函数和方法。虽然在语法上看起来更像是面向对象编程中的类,但实际上,class本质上仍然是基于函数(function)的。 这意味着class所定义的类,最终在JavaScript引擎中仍然被转换为函数。
class的基本语法
ES5中定义对象
在ES5中定义对象通常使用对象字面量(Object literals)或者构造函数来实现。
1. 使用对象字面量
对象字面量是一种简洁的表示方式,可以直接在代码中创建对象。以下是一个示例:
var person = {
firstName: "John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
console.log(person.fullName()); // 输出:John Doe
在上面的示例中,person对象包含了firstName、lastName和fullName三个属性,其中fullName是一个函数。
2. 构造函数
//构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function () {
console.log("你好", this.name, this.age);
};
let p = new Person("张三", 18);
console.log(p); //Person {name: "张三", age: 18}
在上面的示例中,我们首先定义了一个名为Person的构造函数,通过this关键字为对象实例添加属性。然后,通过给Person.prototype对象添加方法,实现了原型方法的定义。最后,通过new关键字创建了一个个Person对象的实例。
ES6使用class定义对象
//class 本质依旧是function
class Person {
//默认会有一个空的constructor()构造函数
constructor(name, age) {
this.name = name;
this.age = age;
}
//class类中的方法 默认都是定义在原型上,不需要function关键字
say() {
console.log("你好", this.name, this.age);
}
}
let p = new Person("张三", 18);
p.say(); //"你好 张三 18"
console.log(p); //Person {name: "张三", age: 18}
console.log(p.name); //"张三"
我们可以看见定义方法不再需要function关键字,同时class内部默认会有一个constructor()。
继承
ES6的Class语法支持继承,使得类之间可以建立父子关系。通过extends关键字可以实现类的继承,子类可以继承父类的属性和方法。
//继承
class Student extends Person {
constructor(name, age, score) {
//super() 表示调用父类的构造函数
super(name, age);
//自己的属性
this.score = score;
}
}
let s = new Student("张三", 18, 100);
console.log(s); //Student {name: "张三", age: 18, score: 100}
需要注意只有调用super()之后,才可以使用this来定义自己的实例属性。 错误示例:
class Student extends Person {
constructor(name, age, score) {
this.score = score;
super(name, age);
}
}
let s = new Student("张三", 18, 100);
console.log(s);
会抛出错误。
get和set属性
ES6的Class还支持Getter和Setter,通过get和set关键字可以定义类的属性访问器。
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
get name() {
console.log("get");
return this._name; // 返回存储在 _name 中的值
}
//set
set name(value) {
console.log("set");
if(){
//做一些判断
}
this._name = value; // 将传入的值存储到 _name 中
}
}
let p = new Person("张三", 18);
console.log(p); // 输出:Person { _name: "张三", age: 18 }
console.log(p.name); // 输出:get 张三
p.name = "李四"; // 输出:set
console.log(p.name); // 输出:get 李四
class的静态方法/方法
ES6的Class支持静态方法。静态方法属于类本身,而不是类的实例,通过在方法前加上static关键字来定义。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
// 静态属性
static type = "human";
// 静态方法
static showName() {
console.log(this.name);
}
}
//调用静态属性
console.log(Person.type);
//调用静态方法
Person.showName();
总结
ES6的Class语法相比传统的原型继承具有许多优势:
- 语法更加简洁明了,更符合传统面向对象编程的思维方式。
- 支持了类的继承,使得代码组织更加清晰。
- 提供了静态方法和属性的支持,更好地满足了一些特殊需求。
- 支持Getter和Setter,使得属性访问更加灵活可控。