首先,我建议你看看这个以他本人(Crockford)为特色的播放列表。它可能很旧,但它确实很好地解释了 JavaScript 的“逻辑”,您的问题在第三个视频中得到了特别解答。
我将通过描述如何在其他传统的面向对象编程语言中描述对象来开始回答这个问题,因为我还想针对您在问题开头发布的 Crockford 评论。
为了理解构造函数,你首先必须对对象有一个很好的理解。在传统的 OOP 语言中,对象是描述对象状态的变量(称为属性或字段)以及描述其行为的函数(称为方法)的集合。在那些(非 JavaScript)语言中,这些对象的“蓝图”称为类。
因此,如果我在 Java 中创建一个 Human 类,一个非常简单的描述将如下所示:
class Human {
String name;
int weight; // kg
int height; // cm
void eat(int foodWeight) {
this.weight += foodWeight;
}
Human(int weight, int height, int name) {
this.weight = weight;
this.height = height;
this.name = name;
}
}
然后,我将使用上面的“蓝图”创建一个对象,如下所示:
Human Joe = new Human(90, 180, "Joe");
现在,我们说Joe
是 的一个实例 Human
,它的体重是 90 公斤,身高是 180 厘米。
在上面的类中,您注意到我有一个函数Human()
用于创建对象并在创建对象时定义它的状态。这本质上是构造函数所做的。
那么 JavaScript 有什么不同呢?
为了在创建时吸引大众(正如您将在我发布的视频系列中听到的那样),JavaScript 结合了一些类似 Java 的语法。根据 Crockford 的说法,这样做的目的是让程序员认为,因为他们已经知道/学习了一些 Java,所以他们可以只学习一些新命令,然后继续使用 JavaScript 编程,而实际上,两者之间的差异两者的相似之处远远超过了它们的相似之处。
在 JavaScript 中,为了以一种看起来像 Java 类的方式创建对象,您可以使用如下函数语法:
var Human = function(name, height, weight) {
this.name = name;
this.height = height;
this.weight = weight;
this.eat = function(foodWeight) {
this.weight += foodWeight;
};
};
然后,如果您想像Joe
我们上面所做的那样定义,您将执行以下操作:
var Joe = new Human("Joe", 180, 90);
您可以看到所示的 Java 和 JavaScript 语法之间的相似之处。因此,回答您的第一个问题:JavaScript 构造函数是在使用 调用时new
创建并返回一个由 指向的隐式创建对象的函数this
。
那么原型是从哪里来的呢?好吧,在 JavaScript 中,函数本身也是 JS 对象,它们有一个名为prototype
. 所以,我们上面创建的构造函数有一个属性Human()
叫做在所有这些情况下。prototype
Joe
Human
例如,其中一种方法Function.prototype
是著名的toString
方法。你可以定义
Human.prototype.toString = function() {
return this.name + " is " + this.height + " cm tall and weighs " + this.weight + " kg";
}
那么,如果你打电话Joe.toString()
或当你做类似的事情时alert(Joe)
自动调用toString()
,返回的值将是“乔身高 190 厘米,体重 80 公斤”。
关于 OOP 和 JavaScript 的更多细节可以在您的问题的上下文中涵盖,但我认为我的回答已经足够长了!我希望这回答了你的问题。