【问题标题】:Understanding Javascript's prototypes coming from a Java and C++ background了解来自 Java 和 C++ 背景的 Javascript 原型
【发布时间】:2014-04-01 15:52:54
【问题描述】:

我的编程背景主要是 Java、C++ 和 C#。我最近开始涉足 Javascript 和 Web 开发,我基本掌握了使用 Javascript 和 JQuery 来处理 DOM 元素以及我在前端需要的其他任何事情。

然而,我似乎无法理解的是 JS 中的原型设计。我已经阅读了几篇关于它的文章和答案,但对我来说仍然不太有意义。我认为正确理解它的最佳方式是对 JS 原型和 C++/Java 类进行某种比较。

所以我的最后一个问题是: 来自 Java/C++ 背景,我需要知道什么才能在我的代码中有效地使用原型?


旁注:像this 这样的问题谈论了两者之间的哲学差异。我真正希望的是解释如何使用面向已经了解如何在 C++ 中使用类的人使用原型进行编程。

【问题讨论】:

标签: java javascript c++ class prototype


【解决方案1】:

原型,以及为什么它们很棒。

在我开始之前,Mozilla 可以比我写得更好:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

和你一样我也有传统 OO 语言的背景,我真正学习的第一门编程语言是 C++,我认为它是最棒的。在许多方面,C++ 是一门很棒的语言,这就是为什么在其中编码the best JavaScript engine

然而,不同之处在于 JavaScript 的工作方式。 C++ 是严格类型化的,类必须包含它们所包含的确切数据类型:

class Rectangle {
    int width, height;
  public:
    void set_values (int,int);
    int area() {return width*height;}
};

与 C++ 不同,JavaScript 中几乎所有内容都是 Object,并且可以使用点符号轻松扩展

var derek = "Derek Howard";
derek.age = 16;

由于 JavaScript 是动态编译的,因此非常灵活。我们可以随时扩展现有对象,而不是像 Object 这样的僵硬骨架。

然而,在许多情况下,我们希望拥有一大堆看起来相同但有自己的数据的对象(就像 C++ 中的类)。这就是prototype 对象发挥作用的地方。

如何在 Javascript 中创建“类”?

我将在 JavaScript 中重新创建上面的矩形对象来演示。

第一步是创建一个Function 来定义你的类名。这应该大写以表示它是一个“类”

第一个函数(大写的)是你的构造函数。您应该使用它将基本初始值传递给您的Object

function Rectangle(width, height) {
    this.width = width || 1;
    this.height = height || 1;
}

|| 操作符使得如果开发人员不将值传递给构造函数,它仍然具有默认值。

然后,要将函数添加到您的“类”中,您需要在原型上创建函数。

Rectangle.prototype.area = function () {
    return this.width * this.height;
}

您已完成创建类!现在使用你的类。

使用类其实和C++很相似。您只需创建一个对象并使用new 关键字:

var bigRec = new Rectangle(42, 100);

然后你就可以直接在新对象上调用你在Rectangle.prototype上创建的函数了:

alert(bigRec.area());

完整代码(JSFiddle:http://jsfiddle.net/howderek/H65qs/

//new class
function Rectangle(width, height) {
    //class properties
    this.width = width || 1;
    this.height = height || 1;
}

//class functions
Rectangle.prototype.area = function () {
    return this.width * this.height;
}

//create a new Rectangle object
var bigRec = new Rectangle(42, 100);
//call functions created from the prototype
alert(bigRec.area());

【讨论】:

  • 哇,这正是我想要的。它为我提供了基本理解的框架,并使我可以轻松地构建它。再次感谢!
【解决方案2】:

我和你有着相似的背景,在我终于明白这一点之前,我已经使用 Javascript 多年了。如果您的问题类似于“我如何编写干净的 Javascript 类并避免因我对事物工作方式的误解而污染我的代码库”,那么我就是这样做的:

我所做的实际上是研究语言 CoffeeScript 的 Javascript。 CoffeeScript 允许您以类似于 Java 等基于类的系统而不是 Javascript 等基于原型的系统的方式编写 OO 代码。然后它编译成(相对)干净的 Javascript,所以你可以看到如何直接实现这样的代码。

如果您查看 CoffeeScript 主页,然后向下滚动到 Classes、Inheritance 和 Super 部分,您将看到一个显示 CoffeeScript 类和生成的 Javascript 实现的窗口(您可以通过单击底部的“加载”按钮对其进行实时编辑并使用它)。当我在本地编写 Javascript 类时,我现在通常会模仿这种风格。还有其他方法……基于原型的系统本质上更灵活……但是这种方法看起来很安全,并且可以保持我的命名空间相对干净(这本质上是 Java 文化的一部分,但不是 Javascript 语言中的默认设置)。

该页面上的 Coffeescript 示例有点忙,因为它实现了类层次结构,这是 Javascript 本身不支持的。如果您删除 Coffeescript 窗格中的所有“继承”和“超级”内容,您会看到更清晰的 Javascript 结果。当然,那么一切都只是继承自“Object”。

【讨论】:

    猜你喜欢
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    相关资源
    最近更新 更多