使用不带“class”关键字的 JavaScript 类
JavaScript 中的类既强大又奇怪。虽然它们允许我们创建具有类似用途的方法和属性的命名对象,但由于语言本身的细微差别,它们经常被误解。
但您是否知道在 2015 年之前,JavaScript 甚至没有关键字class
作为该语言的一部分?
尽管如此,当时的许多程序都使用经典的面向对象编程(OOP)方法,例如使用类、扩展它,甚至添加静态方法。
但没有
class
方法,他们怎么上课呢?
好问题!让我们回答这个问题,然后看看:
- 如何创建一个没有
class
关键字的“类” - 如何“延长”“班级”
- 如何向我们的“类”添加静态方法
创建公共字段contructor
让我们看一个现代的 JavaScript 类:
class User {
name = "Corbin",
username = "crutchcorn",
sayCatchphrase() {
console.log("It depends");
}
}
这是一个相当基本的类,有两个属性(name
和username
)以及一个sayCatchphrase
方法。
然而,尽管ES6 于 2015 年添加了该class
关键字,但直到 ECMAScript 2020 才添加这样的公共字段:
那么2015年之后2020年之前的班级是如何获得房产的呢?
答案?方法constructor
:
class User {
constructor() {
this.name = "Corbin",
this.username = "crutchcorn",
}
sayCatchphrase() {
console.log("It depends");
}
}
事实上,使用这个constructor
方法,我们甚至可以添加该方法:
class User {
constructor() {
this.name = "Corbin",
this.username = "crutchcorn",
this.sayCatchphrase = function() {
console.log("It depends");
}
}
}
当然,这是一个有趣的事实 - 但它并没有回答如何开设课程的问题。
别担心,我们就到了!
创建一个不带class
关键字 的类
在我们回答“如何在没有关键字的 JavaScript 中创建一个类class
”的问题之前,让我们退一步看看 aclass
实际上在做什么......
毕竟,像User
上面这样的类可能会创建一个像这样的对象:
const userObject = {
name: "Corbin",
username: "crutchcorn",
sayCatchphrase: function() {
console.log("It depends");
}
}
知道了这一点,我们可能会认为创建一个没有关键字的类的最佳方法是从函数返回一个对象:
function User() {
return {
name: "Corbin",
username: "crutchcorn",
sayCatchphrase: function() {
console.log("It depends");
}
}
}
果然,如果我们使用以下命令运行这段代码:
const user = new User();
user.sayCatchphrase(); // "It depends"
它将按预期运行。然而,它并不能解决所有情况。例如:
new User() instanceof User; // false
相反,如果我们只是将上述类的constructor
主体转换为函数会怎么样?:
function User() {
this.name = "Corbin";
this.username = "crutchcorn";
this.sayCatchphrase = function() {
console.log("It depends");
}
}
现在,我们不仅使该方法有效,而且instanceof
还有效:
const user = new User();
user.sayCatchphrase(); // "It depends"
new User() instanceof User; // true
原型操作
但是从类更改为函数肯定不允许您以相同的方式更改原型吗?
事实上,确实如此!这就是整个事情的运作方式!
考虑以下代码:
function User() {
this.name = "Corbin";
this.username = "crutchcorn";
}
User.prototype.sayCatchphrase = function() {
console.log("It depends");
}
这与之前添加方法的方法相同this.sayCatchphrase
,但是是通过更改原型来完成的。
我们可以通过运行来测试这段代码是否仍然有效:
const user = new User();
user.sayCatchphrase(); // "It depends"
super
使用该方法 创建扩展类
在讨论基于函数的类扩展之前,我们需要再次讨论一下 ES2020 之前的类创建。
看,当我们将以下代码转换为使用 a 时contructor
:
class Person {
personality = "quirky";
}
class Corbin extends Person {
name = "Corbin";
}
就像这样:
class Person {
constructor() {
this.personality = "quirky";
}
}
class Corbin extends Person {
constructor() {
this.name = "Corbin";
}
}
并尝试初始化它:
const corn = new Corbin()
我们得到以下错误:
Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
at new Corbin (<anonymous>:9:6)
这是因为我们没有使用该super()
方法来告诉我们的扩展类使用父类的方法。
为了解决这个问题,我们将该方法添加到扩展类中constructor
:
class Person {
constructor() {
this.personality = "quirky";
}
}
class Corbin extends Person {
constructor() {
super();
this.name = "Corbin";
}
}
现在我们的Corbin
构造函数工作按预期进行:
const corn = new Corbin();
console.log(corn.name); // "Corbin";
console.log(corn.personality); // "quirky";
使用扩展功能类Object.create
现在让我们将我们的Person
和Corbin
类转换为使用函数而不是class
关键字。
person 类很简单:
function Person() {
this.personality = "quirky";
}
我们可以使用该call
方法将 绑定Person
到this
,Corbin
如下所示:
function Corbin() {
Person.call(this);
this.name = "Corbin";
}
一开始它似乎有效:
const corn = new Corbin();
console.log(corn.name); // "Corbin";
console.log(corn.personality); // "quirky";
但现在,再一次,如果我们调用instanceof
它,它不支持基类:
new Corbin() instanceof Corbin; // true
new Corbin() instanceof Person; // false
为了解决这个问题,我们需要告诉 JavaScript 使用prototype
ofPerson
并将其与 的原型结合起来Corbin
,如下所示:
function Person() {
}
Person.prototype.personality = "quirky";
function Corbin() {
}
Corbin.prototype = Object.create(Person.prototype);
Corbin.prototype.name = "Corbin";
const corn = new Corbin();
corn.personality // "quirky"
corn.name // "Corbin"
const pers = new Person();
pers.personality // "quirky"
pers.name // undefined
请注意我们如何使用
Object.create
其他原型创建基础对象
静态方法
让我们通过讨论如何向函数类添加静态方法来结束本文。
回顾一下,ES2020 类上的静态方法如下所示:
class User {
name = "Corbin",
username = "crutchcorn",
static sayCatchphrase() {
console.log("It depends");
}
}
User.sayCatchphrase(); // "It depends"
User.name // undefined
const corn = new User();
corn.name; // "Corbin"
这可以通过在函数体之外提供函数名称的键来添加:
function User() {
this.name = "Corbin",
this.username = "crutchcorn",
}
User.sayCatchphrase() {
console.log("It depends");
}
User.sayCatchphrase(); // "It depends"
User.name // undefined
const corn = new User();
corn.name; // "Corbin"
结论
这是对如何在没有class
关键字的情况下使用 JavaScript 类的有趣研究。
希望这有助于消除一些关于类在 JavaScript 中如何工作的误解,或者可能只是给出了一些代码为何如此编写的历史背景。
- 点赞
- 收藏
- 关注作者
评论(0)