这两种在JavaScript中创建类的方式有什么区别?

6
这两种创建类的方式有何不同呢?
var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    }
}

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = function() {
        return this.color + ' ' + this.type + ' apple';
    };
}

如何实例化并使用成员?


你只是在创建一个对象而不是一个类。 - Gumbo
3个回答

6

虽然 JavaScript 是一种面向对象的语言,但它并不使用类。在 JavaScript 中,你创建的是“原型”而不是“类”。JavaScript 被认为是一种基于原型的语言。

第一个例子被称为“对象字面量表示法”,用于创建对象(其中的子集通常被称为JSON)。在基于类的语言中,这类似于“静态”类,因为在这种情况下,你不需要创建对象的新实例;它“只是存在”,一旦你定义了它。你不需要实例化它,你可以立即访问 apple 的成员,因为 apple 已经是一个对象。这也类似于在 Java 中创建匿名类。你可以像这样使用它:

alert(apple.getInfo());

使用第二个示例,您正在创建一个原型(而不是类),该原型可用于实例化类型为Apple的对象。您可以像这样使用它:
var redDelicious = new Apple("Red Delicious");
alert(redDelicious.getInfo());

JavaScript允许您修改和添加对象的原型,因此在声明了Apple原型之后,您仍然可以继续添加或更改其内容,例如:
Apple.prototype.size = "7cm";

当你这样做时,所有从Apple原型派生的对象都将获得一个size字段。这是PrototypeJS框架工作的基础,用于修改本机JavaScript对象以添加和修复功能。
请记住,修改本机JavaScript对象的原型被认为是不良实践,因此应尽可能避免这样做。

第一个例子不是一个静态类。它是使用对象字面量语法创建的JS对象。 - SolutionYogi
@SolutionYogi 我知道它不是一个静态类;我在我的答案中提到的第一件事就是JavaScript中没有类。然而,如果他们已经使用过类的语言进行编程,使用人们已经熟悉的比喻来解释JavaScript的基于原型的语法会更容易些。 - Dan Herbert
我仍然觉得称其为“静态类”是完全错误的。静态类不能有状态。我会这样说:在传统的面向对象编程语言中,你不能创建一个没有类的对象,但在JavaScript中,你可以。这就是用户在第一个示例中所做的。 - SolutionYogi
对象字面量和“静态”类有什么相似之处?当你把第一个称为“静态”类时,我觉得很奇怪,但是说第二个是“原型(不是类)”。如果我要在JavaScript和其他面向对象编程语言之间进行类比,我肯定会说第二种情况就像创建“普通”类(如其他面向对象编程语言中的类),而第一个只是一个对象。 - bryantsai
@SolutionYogi和@bryantsa,我更新了我的答案,更清楚地解释了我在答案中试图解释的内容。我同意我所说的并不完全准确。虽然静态类可以有状态,这是每个面向对象编程语言在创建Singleton对象时所依赖的。Java和C#(以及其他语言,我相信)可以在不创建类的情况下拥有一个对象,尽管我认为编译器在创建匿名类时会在IL代码中幕后创建一个类。 - Dan Herbert
如果你想在JavaScript中寻找更熟悉的面向对象行为,可以看一下MooTools框架:http://www.mootools.net/ - Andrew Moore

3

你的第一种方法是JavaScript 对象字面量,可以通过以下方式访问:

apple.type;  // returns "macintosh"
apple.getInfo(); // prints "red macintosh apple"

您还可以像这样添加自己的属性,例如wasGoodprice:

apple.wasGood = "true";
apple.price = "0.50";  
alert(apple.price); // alerts "0.50"

你的第二种方法是实例化一个对象,可以通过以下方式访问:

var myApple = new Apple("macintosh");
myApple.type; // returns "macintosh"
myApple.getInfo(); // returns "red macintosh apple"

如果您想向Apple对象添加属性,您需要使用prototype关键字:

Apple.prototype.price = "0.50";
Apple.prototype.wasGood = "true";
alert(myApple.price); // alerts "0.50"

3
以下是一些差异:
  • 第一种方法不完整,最后一个关闭括号后面缺少一个分号。

  • 第一种方法创建一个对象,而第二种方法只声明了一个可以用于创建对象的构造函数。

  • 第一种方法只能创建一个对象,而第二种方法可以通过关键字new创建多个对象。

  • 第一种方法不能接受任何参数来影响对象的初始化,而第二种方法可以。

第一种方法创建一个单一对象并将其赋值给变量apple,您可以使用该变量来访问成员:

alert(apple.type);

第二种方式是使用new关键字创建实例:
var green = new Apple('Signe Tillisch');
alert(green.type);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接