JS中的类?class语法糖??? 两分钟秒了
作者:想吃绵绵冰
顺便吆喝一声,如果你计算机、软件工程、电子等相关专业本科及以上学历,欢迎来共事。
前端 / 后端 / 测试等均可投→技术大厂机会。
前言
JS 中有类?我们都知道 JavaScript 是基于原型的语言,并没有内置的类概念。但从 ES6 开始,JavaScript 引入了 class
关键字作为语法糖,它提供了一种更简洁、更类似于传统面向对象编程的语法来创建对象。
class
关键字在语法上类似于许多其他基于类的语言,如 Java 或 C++,但 JavaScript 的类仍然是基于原型的。
正文
class 语法糖有哪些基本用法?
一,定义类
在 JavaScript 中,你可以使用 class
关键字来定义一个类。类是一个抽象的概念,它描述了具有相同属性和方法的对象的集合。在类中一定有一个构造器函数 constructor,我们可以在 constructor 中接收参数,将我们需要的参数都加进去。
class Person {
constructor(name, age) {
this.name = name;
this.age = age
}
sayHello() {
console.log(`Hello, my name is ${this.name} and my age is ${this.age}`);
}
}
在上面的例子中,我们定义了一个名为 MyClass
的类,它有一个构造函数(constructor
)和一个方法(sayHello
)。构造函数在创建类的实例时被调用,它接受一个参数 name
并将其存储在实例上。sayHello
方法用于打印一条问候信息。
二, 创建类的实例
创建类的实例就是将类实例化,我们使用 new
关键字调用类的构造函数来创建一个新的对象,这个对象就是该类的实例。
这个新创建的对象会继承类的所有属性和方法(除非它们是静态的),并且可以有自己的状态(即实例属性和方法)。这里以我自己为例
class Person {
constructor(name, age) {
this.name = name;
this.age = age
}
sayHello() {
console.log(`Hello, my name is ${this.name} and my age is ${this.age}`);
}
}
let p = new Person('绵绵冰', 18);//调用然后传入参数
console.log(p);
p.sayHello();
在上面的例子中,我在 class 类里面传入了参数,定义了一个 sayHello 方法;我将这个类实例化为 p,这个 p 可以访问我在类中定义的方法
类的实例对象可以访问类中的方法,就像原型一样
类的原型机制
为什么类能实现这样的功能呢?当然和原型离不开关系,因为我们都知道 JS 是基于原型的语言。js 的类也是基于原型的。
他的运行机制主要有三步:
1. 类定义
因为当你定义一个类时,实际上你定义了一个构造函数(通过 class
关键字),并且在这个构造函数上挂载了一些属性和方法。这些属性和方法实际上是定义在构造函数的 prototype
对象上的。
2. 创建实例
当你使用 new
关键字创建类的实例时,JavaScript 引擎会执行以下步骤:
- 创建一个新的空对象。
- 将这个新对象的
__proto__
设置为类的prototype
对象。 - 执行构造函数,并将
this
绑定到新创建的对象上。 - 如果构造函数返回了一个对象,那么这个对象将成为
new
表达式的返回值;否则,返回新创建的对象。
3. 访问属性和方法
由于实例的__proto__
指向了类的 prototype
对象,所以当你尝试访问实例上的一个属性或方法时,JavaScript 会首先在实例自身上查找。如果找不到,它会继续在实例的原型链上查找,直到找到为止,或者直到原型链的末尾(即 Object.prototype
)
三,继承类
既然 JS 中的类也是基于原型的,那么就一定和原型一样有类似的继承方法。
在 JS 中,我们可以使用 extends
关键字来让一个类继承另一个类的属性和方法。这允许你创建更复杂的类结构,并实现代码的重用。
class BasePerson { // BasePerson,表示它是一个基础类
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hello, my name is ${this.name} and my age is ${this.age}`);
}
}
class Person extends BasePerson { // Person,表示它是从 BasePerson 继承的子类
constructor(name, age) {
super(name, age); // 调用父类的构造函数,并传递所有参数
}
introduce() {
console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`);
}
}
const p = new BasePerson('绵绵冰', 18);
const p2 = new Person('绵绵冰', 20)
console.log(p);
console.log(p2);
p2.introduce();
p2.sayHello();
在上面的例子中,Person 就继承了 BasePerson 的 class 里面的属性和方法,添加了新的方法 introduce 来介绍自己。
四, 静态方法
在 JavaScript 中,我们可以使用 static
关键字来定义静态方法。静态方法是挂载在类上的方法,而不是类的实例上。这意味着我我们可以直接通过类名来调用静态方法,而不需要创建类的实例。
class greet {
static greet() {
console.log('Hello from a static method!');
}
}
greet.greet(); // 输出: Hello from a static method!
在这个例子中,我们定义了一个名为 greet
的类,并在其上定义了一个静态方法 greet
。我们直接通过类名调用了这个方法,而无需创建类的实例。
五,类中访问器
这是一种特殊类型的方法,用于读取和写入对象的属性。访问器由 getter 和 setter 方法组成。getter 方法是一个没有参数的方法,用于返回与对象属性相关联的值。setter 方法则接收一个参数(即要写入属性的值),并用于修改与对象属性相关联的值。
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
// getter方法,用于读取_name属性
get name() {
return this._name;
}
get age() {
return this._age;
}
// setter方法,用于设置_name属性
set age(newAge) {
this._age = newAge;
}
set name(newName) {
this._name = newName;
}
}
const person = new Person('绵绵冰', 18);
// 使用getter方法读取属性
console.log(person.name);
console.log(person.age);
// 使用setter方法设置属性
person.name = '绵绵冰2号';
person.age = 20;
// 再次使用getter方法读取属性,验证setter方法是否生效
console.log(person.name);
console.log(person.age);
在上面这个简单的例子中,我们通过 get 方法拿到了 name 和 age 并且将他们转化为了私有属性(使用下划线前缀表示私有属性,尽管在 JavaScript 中并不是真正的私有),再通过 set 将这些属性设置为新的属性值。但是这个简单的例子存在一些问题,我们需要对传入的参数进行一些判断
- 使用
typeof
判断输入参数的类型 - 使用
trim()
移除字符串开头和结尾的空白符 - 判断经过 trim 处理后的字符是不是一个空字符,不是空字符返回 true
- 使用
&&
将两个判断连接,只有当这两个判断都为 true 时,整个表达式才会返回 true - 否则 console.error
class Person { constructor(name, age) { this._name = name; this._age = age; } get name() { return this._name; } get age() { return this._age; } set name(newName) { // 在这里添加一些验证逻辑 if (typeof newName === 'string' && newName.trim() !== '') { this._name = newName; } else { console.error('无效'); } } set age(newAge) { if (typeof newAge === 'number' && newAge >= 0) { this._age = newAge; } else { console.error('无效'); } } } const person = new Person('绵绵冰', 18); console.log(person.name); console.log(person.age); person.name = '绵绵冰2'; person.age = 20; console.log(person.name); console.log(person.age); // 尝试设置一个无效的值,查看setter方法中的验证逻辑是否生效 person.age = '十八'; // 这将触发setter方法中的console.error
- 点赞
- 收藏
- 关注作者
评论(0)