简体   繁体   English

了解来自Java和C ++背景的Javascript原型

[英]Understanding Javascript's prototypes coming from a Java and C++ background

My programming background is largely in Java, C++, and C#. 我的编程背景主要是Java,C ++和C#。 I've been getting into Javascript and web development recently and I have a basic grasp of using Javascript and JQuery to do things like manipulate DOM elements and whatever else I need on the front end. 我最近进入了Javascript和Web开发,我基本掌握了如何使用Javascript和JQuery来操作DOM元素和前端需要的其他东西。

What I can't seem to wrap my head around, however, is prototyping in JS. 然而,我似乎无法解决的问题是在JS中进行原型设计。 I've read several articles and answers about it, but it still doesn't quite make sense to me. 我已经阅读了几篇关于它的文章和答案,但它对我来说仍然没有意义。 I think the best way for me to properly understand it is with some sort of comparison between JS prototypes and C++/Java classes. 我认为正确理解它的最好方法是在JS原型和C ++ / Java类之间进行某种比较。

So my final question is: Coming from a Java/C++ background, what do I need to know to be able to effectively use prototypes in my code? 所以我的最后一个问题是:来自Java / C ++背景,我需要知道什么能够在我的代码中有效地使用原型?


Side note: questions like this talk about the philosophical differences between the two. 附注:这样的问题说说两者之间的哲学分歧。 What I'm really hoping for is an explanation of how to program with prototypes geared towards someone who already understands how to use classes in C++. 我真正希望的是解释如何使用原型来编程,这些原型面向已经理解如何在C ++中使用类的人。

Prototypes, and why they are awesome. 原型,以及为什么它们很棒。

Before I start, Mozilla can write this guide better than me: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript 在开始之前,Mozilla可以比我更好地编写本指南: https //developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

Just like you I also have a background in traditional OO languages, my first programming language that I really learned was C++, and I thought it was the greatest. 就像你一样,我也有传统OO语言的背景,我真正学到的第一种编程语言是C ++,我认为它是最好的。 In many ways, C++ is a fantastic language, that's why the best JavaScript engine is coded in it. 在很多方面,C ++是一种很棒的语言,这就是为什么最好的JavaScript引擎被编码的原因。

The difference however, lies in how JavaScript works. 然而,区别在于JavaScript的工作原理。 C++ is strictly typed, and classes must contain the exact datatypes of what they contain: C ++是严格类型的,并且类必须包含它们包含的确切数据类型:

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

Unlike C++, nearly everything in JavaScript is an Object and and be easily extended with dot notation 与C ++不同,JavaScript中的几乎所有内容都是一个Object ,并且可以使用点表示法轻松扩展

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

Since JavaScript is compiled on the fly, it is extremely flexible. 由于JavaScript是即时编译的,因此非常灵活。 Rather than a rigid skeleton of what an Object can be, we can just extend an existing object whenever we want. 我们可以随时扩展现有对象,而不是Object的刚性骨架。

In many situations however, we want to have a whole bunch of Objects that look the same , but have their own data (like a class in C++). 然而,在许多情况下,我们希望有一大堆看起来相同的对象,但是有自己的数据(比如C ++中的类)。 This is where the prototype object comes into play. 这是prototype对象发挥作用的地方。

How can I make a "class" in Javascript? 如何在Javascript中创建“类”?

I will recreate the rectangle object above in JavaScript to demonstrate. 我将在JavaScript中重新创建上面的矩形对象来演示。

The first step is to create a Function that defines your class name. 第一步是创建一个定义类名的Function This should be capitalized to signify it is a "class" 这应该大写,以表示它是一个“类”

The first function (the one that is capitalized) is your constructor. 第一个函数(大写的函数)是你的构造函数。 You should use it to pass essential inital values to your Object 您应该使用它将必要的初始值传递给您的Object

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

The || || operator makes it so if the developer doesn't pass a value to the constructor it still has default values. 运算符使得如果开发人员没有将值传递给构造函数,它仍然具有默认值。

Then, to add functions to your "class" you will want to create functions on the prototype. 然后,要向“类”添加函数,您需要在原型上创建函数。

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

You're done creating the class! 你已经完成了创建课程! Now to use your class. 现在用你的班级。

To use the class is actually very similar to C++. 使用该类实际上与C ++非常相似。 You simply create an object and use the new keyword: 您只需创建一个对象并使用new关键字:

var bigRec = new Rectangle(42, 100);

Then you can call the functions you created on Rectangle.prototype directly on the new object: 然后,您可以直接在新对象上调用在Rectangle.prototype上创建的函数:

alert(bigRec.area());

The Full Code (JSFiddle: http://jsfiddle.net/howderek/H65qs/ ) 完整代码(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());

I came from a similar background as you, and I'd done Javascript for years before I finally made sense of this. 我来自与你相似的背景,在我最终理解这一点之前,我已经做了多年的Javascript。 If your question is along the lines of "How do I write clean Javascript classes and avoid polluting my codebase with my misunderstandings of the way things work," here's how I did it: 如果你的问题是“我如何编写干净的Javascript类,并避免因我对工作方式的误解而污染我的代码库”,这就是我如何做到的:

What I did was actually study the Javascript that the language CoffeeScript to. 我所做的实际上是研究CoffeeScript语言的Javascript。 CoffeeScript lets you write OO-code in a manner that resembles Class-based systems like Java, rather than Prototype-based systems like Javascript. CoffeeScript允许您以类似于基于类的系统(如Java)的方式编写OO代码,而不是像Javascript那样基于Prototype的系统。 And then it compiles down to (relatively) clean Javascript, so you can see how such code could be implemented directly. 然后它编译为(相对)清理Javascript,因此您可以看到如何直接实现此类代码。

If you look at the Coffeescript homepage, and then scroll down to the Classes, Inheritance, and Super section, you'll see a window that shows CoffeeScript classes and the resulting Javascript implementation (you can edit it live and play with it by clicking on the Load button down at the bottom). 如果您查看Coffeescript主页,然后向下滚动到Classes,Inheritance和Super部分,您将看到一个窗口,其中显示了CoffeeScript类以及生成的Javascript实现(您可以通过单击实时编辑它并使用它进行播放)底部的加载按钮)。 When I write Javascript classes natively, I generally mimic this style now. 当我本地编写Javascript类时,我现在通常会模仿这种风格。 There are other ways...prototype-based systems are inherently more flexible...but this way seems safe and keeps my namespaces relatively clean (something that's inherently part of Java culture but not the default in the Javascript language). 还有其他方法......基于原型的系统本质上更灵活......但这种方式似乎是安全的并且使我的命名空间相对干净(这本身就是Java文化的一部分,但不是Javascript语言中的默认)。

The Coffeescript example on that page is a little busy because it implements a class heirarchy, something not natively supported by Javascript. 该页面上的Coffeescript示例有点忙,因为它实现了一个类heirarchy,这是Javascript本身不支持的。 If you delete all of the "inheritance" and "super" stuff in the Coffeescript pane, you'll see much cleaner Javascript results. 如果删除Coffeescript窗格中的所有“继承”和“超级”内容,您将看到更清晰的Javascript结果。 Of course, then everything just inherits from "Object". 当然,那么一切都只是从“对象”继承而来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM