请考虑以下示例代码:
class Test {
say() {
console.log("I'm a test.");
}
}
let TestFromClass = new Test();
let TestFromObject = {
say() {
console.log("I'm also a test.");
}
};
TestFromClass.say(); // Output: I'm a test.
TestFromObject.say(); // Output: I'm also a test.
我知道可以创建对象,比如TestFromObject
,而不必先创建一个带有class
关键字的类。class
有必要吗?这两种对象之间有区别吗?如果有区别,显式使用class
有什么影响?
5条答案
按热度按时间pgccezyw1#
使用
new
创建一个新对象,其内部原型是类的原型。例如:这对于创建多个对象很有用。这样做的通常原因是每个对象都可以具有某种关联的 state -通常是其属性值。例如,
Person
对象可能具有name
和age
属性。但是,如果没有数据与示例关联(如原始代码中的
TestFromClass
),那么拥有示例就没有多大意义。如果目的只是将命名函数收集到数据结构中,则TestFromObject
方法更有意义。也就是说,有时候需要一个类有一些与之关联的函数(比如
say
),这些函数与其数据的示例没有任何关系,* 同时 * 仍然能够创建示例--也许可以使用原型上的其他方法。这并不罕见,可以通过使非示例相关的函数static
来实现:nukf8bse2#
类或多或少只是原型的语法糖:
这两种情况与直接创建对象的区别在于方法属于原型,而不是直接属于对象。
代码
TestFromClass.say()
必须遍历原型链才能找到say
方法,而TestFromObject直接拥有该方法。除此之外,没什么区别。
6jygbczu3#
这两种对象之间有区别吗?如果有,显式使用class有什么效果?
实际上没有什么有意义的区别,但它确实有一些小的影响:
__proto__
属性名,否则其原型将始终为Object.prototype
。(请注意,__proto__
是正式的“可选”,JavaScript引擎不必提供它。)当您使用new X
创建它时,假设X
是使用class
语法创建的构造函数,结果将具有原型X.prototype
。class X
中的方法放在对象 * 继承 * 的X.prototype
(非static
的方法)上。qvsjd97n4#
对象有两种形式:声明(文字)形式和构造形式。
对象的文本语法如下所示:
构造的窗体如下所示:
构造形式和文本形式产生的对象完全相同,唯一的区别是可以在文本声明中添加一个或多个键/值对,而对于构造形式的对象,必须逐个添加属性。
注意:使用“构造形式”来创建对象是非常罕见的,你可能总是想使用字面语法形式,这对于大多数内置对象也是一样的。
**P.S.**要了解更多详细信息,请访问https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/this-object-prototypes/ch3.md
mzillmmw5#
所以你创建了一个叫做
Test
的类,它是基类,然后你添加了一个叫做say() {}
的方法。然后,您创建了
Test
类的一个示例,如下所示:在它下面创建了一个名为
TestFromObject
的普通JavaScript对象:是的,它们都将打印出您对它们的方法的输出:
只有充分利用所创建类的功能,例如,像这样利用
cconstructor()
函数,差异才会开始:现在,当我们使用
new
关键字作为类名时,构造函数会自动被调用,通过构造函数,你也可以访问this
,如下所示:它允许您执行以下操作:
构造函数传统上用于在类或类的特定示例中进行一些初始设置。
构造函数通常在创建类的新示例时通过使用一些参数来使用。也许你想指定你创建的Test类有50个问题。你可以像这样传入一个对象到新的Test示例:
你可以随意调用这个对象,我们只调用对象
examination
,你可以设置这个对象的问题数量。现在你把这个对象传递给构造函数并调用这个对象,
examination
如下所示:另一件你可以用类对象做的事情是创建一个子类来扩展你的基类的功能,然后你也可以给它添加一些定制的功能。
现在,您的测验继承了Test类中的所有方法、函数、属性等,并在其中定义了其他方法。
现在,为了确保父类的构造函数也被调用,我可以在构造函数中使用
super()
关键字:然后,您可以示例化该子类,如下所示:
最后打印出来