wiki 百科对 class 的定义:
在面向对象的编程中,class 是用于创建对象的可扩展程序代码模板,它为对象提供了状态(成员变量)的初始值和行为(成员函数或方法)的实现。
在开发中,我们经常需要创建许多相同类型的对象,比如用户(user)、商品(goods)等等,而现代 JavaScript 中的 class 就是为更便捷的解决以上问题。
class 语法
class MyClass {
// class 方法
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
let class = new MyClass()
我们通过使用 new MyClass()
来创建具有上述列出的所有方法的新对象,new
会自动调用 constructor()
方法。
有一点需要注意:类的方法之间没有逗号。 不要把这里的符号与对象字面量相混淆。在类中,不需要逗号
class 实现的原理
在 JavaScript 中,类是一种函数。
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// 佐证:User 是一个函数
alert(typeof User); // function
class User {...}
构造实际上做了如下的事儿:
- 创建一个名为
User
的函数,该函数成为类声明的结果。该函数的代码来自于constructor
方法(如果我们不编写这种方法,那么它就被假定为空)。 - 存储类中的方法,例如
User.prototype
中的sayHi
。
class 不仅仅是语法糖
// 用纯函数重写 class User
// 1. 创建构造器函数
function User(name) {
this.name = name;
}
// 函数的原型(prototype)默认具有 "constructor" 属性,
// 所以,我们不需要创建它
// 2. 将方法添加到原型
User.prototype.sayHi = function() {
alert(this.name);
};
// 用法:
let user = new User("John");
user.sayHi();
这个定义的结果与使用类得到的结果基本相同。因此,这确实是将 class
视为一种定义构造器及其原型方法的语法糖的理由。
但它们之间存在重大差异:
1.通过 class
创建的函数具有特殊的内部属性标记 [[IsClassConstructor]]: true
。
2.类方法不可枚举
3.类总是使用 use strict
。 在类构造中的所有代码都将自动进入严格模式。
类语法的其他功能
(1)类表达式
就像函数一样,类可以在另外一个表达式中被定义,被传递,被返回,被赋值等。
let User = class {
sayHi() {
alert("Hello");
}
};
(2)class 字段
之前,我们的类仅具有方法。
“类字段”是一种允许添加任何属性的语法。
例如,让我们在 class User
中添加一个 name
属性:
class User {
name = "John";
sayHi() {
alert(`Hello, ${this.name}!`);
}
}
new User().sayHi(); // Hello, John!
(3)丢失 this 问题
如果一个对象方法被传递到某处,或者在另一个上下文中被调用,则 this
将不再是对其对象的引用。
例如,此代码将显示 undefined
:
class Button {
constructor(value) {
this.value = value;
}
click() {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // undefined
我们有两种可以修复它的方式:
- 传递一个包装函数,例如
setTimeout(() => button.click(), 1000)
。 - 将方法绑定到对象,例如在 constructor 中。
类字段提供了另一种非常优雅的语法:
class Button {
constructor(value) {
this.value = value;
}
click = () => {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // hello
类字段 click = () => {...}
是基于每一个对象被创建的,在这里对于每一个 Button
对象都有一个独立的方法,在内部都有一个指向此对象的 this
。我们可以把 button.click
传递到任何地方,而且 this
的值总是正确的。
下文我们继续说类继承。
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!