(开源)JavaScript 原型 OO 示例
赏金编辑:
我正在寻找以纯粹原型OO范例(想想Self)编写的代码。不是原型面向对象和经典面向对象的混合体。我不想看到通用的 OO 包装器,而只想看到典型的 OO 技术的使用,并且仅原型的 OO 技术。
参考相关问题:
在上面的问题中,我主要集中于
可以这样编写原型 OO 吗?
我们需要构造函数和初始化逻辑吗?有哪些替代方案?
新问题:
基本上在大型开源项目中是否有任何javascript原型面向对象的好例子?
澄清:
我必须澄清我对原型面向对象的含义:
- 没有类。只有对象。
- 对类概念的模拟零,同样只有对象和克隆对象来创建新对象。
进一步澄清原型 OO:
JavaScript 中的原型 OO 和经典 OO 模拟之间的差异是一个非常灰色的区域。这并不是说我重视避免经典的面向对象。我想以学术方式学习原型 OO,而不是学习经典 OO 模拟和原型 OO 的(可能更优化)组合。
这就是为什么我“禁止”类,只是为了我可以以纯粹的方式看到这些技术并扩展我自己的 OO 工具包。
示例:
像 jQuery 这样的流行示例无法满足第二个标准。 jQuery
对象是一个大的类模拟。它专注于从类创建新对象,而不是克隆现有对象。
如果我真的知道任何使用“纯粹”原型面向对象的示例,我就会向您展示。我相信 99% 的 JavaScript OO 都受到经典模拟的严重影响。
奖励分
如果
- 它有很好的注释/记录
- 有单元测试
- 在 github 上。
我还将接受有关如何编写超越简单的 hello world 应用程序的原型 OO 代码的文章/教程和示例。
Bounty Edit:
I'm looking for code written in a pure prototypical OO paradigm (think Self). Not a mixture of prototypical OO and classical OO. I don't want to see generic OO wrappers but simply usage of prototypical OO techniques and only prototypical OO techniques.
Reference Related Question:
In the above question I mainly focused on
Can write prototypical OO like this?
Do we need constructors and initialization logic, What are the alternatives?
New question:
Basically are there any good examples of javascript prototypical OO in large open source projects?
Clarification:
I will have to clarify what I mean with prototypical OO :
- There are no classes. There are only Objects.
- There is zero emulation of the concepts of classes, again there is only objects and cloning objects to create new objects.
Further Clarification of Prototypical OO:
The difference between prototypical OO in JavaScript and classical OO emulation is a very grey area. It's not that I value avoiding classical OO. I want to learn prototypical OO in an academic fashion in it's own right, without learning the (probably more optimum) combination of classical OO emulation and prototypical OO.
This is why I "ban" classes, just so that I can see these techniques in a pure fashion and extend my own OO tool kit.
Examples:
Popular examples like jQuery fail to meet the second criteria. The jQuery
object is one big class emulation. It focuses on creating new objects from a class rather then cloning existing objects.
If I actually knew any example of using "pure" prototypical OO I would have shown you. I believe 99% of JavaScript OO is too heavily influenced by classical emulation.
Bonus points
If
- It's well comented / documented
- Has unit tests
- Is on github.
I will also accept articles / tutorials and examples on how to write prototypical OO code that goes beyond your trivial hello world application.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你不会找到它。
我不久前就在寻找这类东西,这就是我发现的: 自述文件组织没有课程的程序(看看Citeseer PDF 版本。)本文讨论了最佳实践对于Self,原始的原型语言,最佳实践是使用“traits object idiom”,即让你的对象继承自“traits object”仅包含方法,不包含对象特定数据。换句话说,一个可疑地像类的对象。
甚至原始的原型语言也模拟类。
You will not find it.
I went looking for this sort of thing a while ago, and this is what I found: the Self Paper Organizing Programs Without Classes (Look at Citeseer for a PDF version.) This paper discusses the best practices for Self, the original prototypal language, and the best practice is to use the "traits object idiom", which is to have your objects inherit from "traits objects" that contain only methods, and no object specific data. In other words, an object that is suspiciously like a class.
Even the original prototypal language emulates classes.
你看过 OMeta/JS 吗? OMeta是一种基于Smalltalk和Self的实验性研究模式匹配语言。 OMeta/JS 是使用原型 OO 的 javascript 实现。
它有很好的评论和记录,有很多例子。它也在 Github 上。
http://tinlizzie.org/ometa-js/
https://github.com/alexwarth/ometa-js
编辑:OMeta 是 Alexander Warth 博士论文的成果。
Have you taken a look at OMeta/JS? OMeta is an experimental research pattern matching language based on Smalltalk and Self. OMeta/JS is an implementation in javascript using prototypical OO.
It is well commented and documented with many examples. It is also on Github.
http://tinlizzie.org/ometa-js/
https://github.com/alexwarth/ometa-js
Edit: OMeta is the result of Alexander Warth's PhD disertation.
我不太确定您在寻找什么,但我当前的框架允许您以面向对象的方式进行编程,如下所示:
然后您可以编写如下代码:
我在这里不尝试模拟经典的面向对象。我试图提供一种方便且有用的方法来声明继承、混合、接口和通用 OO 概念,以便开发人员可以轻松编写此类 OO 代码。这也让我有机会完成我的自动加载组件,这样您就不再需要处理依赖项,并且可以进行自定义构建并享受更快的开发,因为不需要每次页面加载加载 100 个脚本。
如果你想学习原型的 OO 概念,我认为你应该编写某种继承系统。查看 Dojo Toolkit 或 ExtJS。需要记住的一件好事是,基于原型的系统扭曲和破坏,它们比基于类的 OO 语言更强大。在我看来,编写原型代码没有唯一正确的方法。
但我担心大多数(如果不是全部)继承系统可能看起来都在模仿经典的面向对象。在我看来,我的框架没有,但它甚至还没有完成。
I'm not exactly sure what you are looking for, but my current framework allows you to program in OO fashion like so:
And then you can write code like:
I am not trying to emulate classical OO here. I am trying to make a convenient and useful way to declare inheritance, mixins, interfaces, and general OO concepts so that it becomes easy for the developer to write such OO code. This also gives me the chance to finish my auto loading component so that you no longer take care of dependencies and you can make custom builds and enjoy faster development thanks to not needing to load 100 scripts per each page load.
If you want to learn prototypical OO concepts, I think you should write some kind of inheritance system. Take a look at Dojo Toolkit or ExtJS. A good thing to remember is that Prototype-based systems twist and mangle, they are more powerful than Class-based OO languages. In my opinion, there is no single right way to write prototypal code.
I'm afraid though that most if not all inheritance systems might look like they emulate classical OO. In my opinion, my framework does not, but then it's not even finished.
可能是 JSLint (Crockford 是原型继承的支持者,但我还没有仔细梳理它的每一寸)。它看起来也比面向对象更实用,但我预计真正拥抱原型继承的代码通常就是这种情况。
Probably JSLint (Crockford's a proponent of prototypical inheritance, but I haven't combed through every inch of it). It's also looks more functional than Object Oriented, but then I expect that's generally the case with code that truly embraces prototypical inheritance.
在我的框架中,一切都是对象或“接口”。
接口定义了对象可能具有的通用函数(方法/property_gets/property_sets)。
您可以像这样创建一个接口:
var some_interface = GetInterface(constructor, interface_setup,parent_interface..)
您可以指定任意数量的parent_interface。因此,如果
interface_A
同时继承interface_B
和interface_C
,则可以按如下方式创建interface_A:GetInterface(constructor,interface_setup,interface_B,interface_C) ;
如果
interface_A
继承interface_X
并且interface_X
继承interface_Y
,则interface_A
将具有interface_X
和interface_Y
所具有的所有功能。不需要构造函数的接口会将构造函数参数保留为 null。 interface_setup 是一个如下所示的函数:
proto 参数指向的对象有 4 个方法:
SetM
、ShadowM
、SetP
和ShadowP
。您可以使用这 4 种方法设置您的界面。
该框架还提供接口的延迟实例化。 (换句话说,安装代码在实际第一次需要之前永远不会真正运行)。
该框架的局限性至少需要支持
Object.keys
、Object.getOwnPropertyDescriptor
和Object.defineProperty
。 (换句话说,它适用于最新版本的 FireFox、IE、Chrome、Safari,但不适用于 Opera)TestPage2.html:
TestPage.html:
Js.js :
In my framework, everything is an object or an "interface".
Interfaces define the common functions (methods / property_gets / property_sets) that objects may have.
You create an interface like this:
var some_interface = GetInterface(constructor, interface_setup, parent_interface..)
You can specify any number of parent_interfaces. So if
interface_A
inherits bothinterface_B
andinterface_C
, you can create interface_A as such:GetInterface(constructor, interface_setup, interface_B, interface_C);
If
interface_A
inheritsinterface_X
andinterface_X
inheritsinterface_Y
, theninterface_A
will have all the functions which bothinterface_X
andinterface_Y
has.Interfaces which do not require a constructor will leave the constructor argument as null. The interface_setup is a function which looks like this:
The object that the proto argument points to has 4 methods:
SetM
,ShadowM
,SetP
, andShadowP
.You use these 4 methods to setup your interface.
This framework also provides lazy instantiation of interfaces. (in other words the setup code will never actually be ran until it is actually first needed).
Limitations of this framework requires at least support for
Object.keys
,Object.getOwnPropertyDescriptor
andObject.defineProperty
. (In other words it works in the latest versions of FireFox, IE, Chrome, Safari but not Opera)TestPage2.html:
TestPage.html:
Js.js:
ExtJS 是 JavaScript OO 的一个很好的例子。它在 JavaScript 中实现了一个非常复杂的企业级 OO 层次结构,可以立即执行许多操作。这可能是一本令人畏惧的读物(我上次检查 3.X 时,它是超过 1MB 的原始、未压缩的 JavaScript),但它会给你很多想法。您可以首先查看文档以获得高级视图。
ExtJS is an excellent example of JavaScript OO. It implements a really sophisticated, enterprise-level OO hierarchy in JavaScript that does a lot of things out of the box. It may be a daunting read (last I checked in 3.X, it was over 1MB of raw, uncompressed JavaScript), but it'd give you a lot of ideas. You could start out by reviewing the documentation to get a high-level view.
我目前正在使用继承插件模型,它尝试将原型 OO 模式与 jQuery 插件模式结合起来。它在我的答案中详细发布: 将一个类附加到jQuery 对象
注意: 不要因提及
Class
这个词而被拒绝I'm currently using a inheritance plugin model which attempts to combine the prototypical OO pattern with jQuery plugin pattern. Its posted in detail in my answer here: attaching a class to a jQuery object
Note: Do not get turned away by mention of the word
Class
下面的示例展示了您正在寻找的 OO 编程的基础。最好的现实例子可能是 jQuery。
在学习 JavaScript 时,您必须记住,它实际上比 C 或 Java 更接近于Scheme。基本上它是C 语法中的Scheme。
在 JavaScript 中几乎不应该使用“new”,尤其是在编写 API 时。似乎添加了“new”运算符是因为 JavaScript 不确定其原型框架。对于我们大多数开始使用 C、C++ 和 Java 等经典语言进行编程的人来说,这似乎很奇怪,因为“新”通常正是我们正在寻找的东西,因为它很容易翻译。
你问为什么我不应该使用“新”?好吧,由于“new”的实现,您可能会无意中开始清除全局数据(记住,不是 JavaScript 函数中的所有内容)。如果您碰巧陷入这种情况,那么您将不会看到任何错误或通知,而只会看到程序中不可预测的行为。此外,对于“this”在您的“类”中实际绑定的内容可能不清楚,也可能不清楚。
当您编写一个打算用“new”调用的函数而用户不使用“new”时,就会发生在不知情的情况下擦除全局内存的问题。提示为什么在 API 中使用它会导致用户不满意。
面向对象的“类”和继承的正确方法是使用 JavaScript 最强大的属性……对象。
你可以编写一个函数来返回一个对象来建立一个“类”。你放入这个对象中的任何东西(数字、字符串、方法等)都是你的“类”的公共属性。您在函数中编写的任何不在返回的对象内部的内容都是私有的。
要从“类”继承,您可以简单地初始化将返回到“基类”结果的对象,然后扩展其功能。
以下代码部分将展示如何使用私有和公共变量构造基类,以及如何进行 2 级继承。
基础对象
继承
编辑:有人提醒我没有使用“原型”对象。我这样做是为了避免必须使用“new”运算符,如上面的文字所述。为了完整起见,我将使用下面的原型对象给出一个示例...
原型对象的继承
请随时向我询问有关本文的任何内容。享受。
Here is an example showing the basis of the OO programming that you are looking for. Best real-world example would be jQuery probably.
When learning JavaScript, you have to keep in mind that it is actually closer to Scheme than it is C or Java at its roots. Basically it is Scheme in C's syntax.
There is almost never a case where you should use "new" in JavaScript, especially if you are writing APIs. It seems as the "new" operator was added in because it JavaScript was not sure about its prototypal framework. For most of us that start programming with classical languages such as C, C++, and Java, this seems odd, as "new" is generally exactly what we are looking for, because it translates easily.
Why shouldn't I use "new" you ask? Well, due to the implementation of "new", you can inadvertently start wiping out your global data (which remember, is everything not in a function in JavaScript). If you happen to fall prey to this, then you will not see any errors, or notifications, but only see unpredictable behavior in your program. Also, it may or may not be clear as to what "this" actually is bound to within your "class".
The wipe out your global memory without knowing it problem mainly occurs when you write a function that is intended to be called with "new" and the user does not use "new". Hints why using it in APIs can lead to unhappy users.
The correct way to object oriented "classes" and inheritance is to use JavaScript's most powerful attribute...the object.
You can write a function to return an object to establish a "class". Anything you put into this object (numbers, strings, methods, etc.) are all public properties of your "class". Anything you write within your function that is not inside that object that is being returned, is private.
To inherit from your "class", you can simply initialize your object that you will be returning to a your "base class" result and then extend its functionality.
The following sections of code will show how to construct a base class with private and public variables, and the do 2 levels of inheritance.
Base Object
Inheritance
EDIT: I was alerted that I did not use the "prototype" object. I did this, as to avoid HAVING to use the "new" operator, as mentioned in the text above. For completeness, I will give an example using the prototype object below...
Inheritance with the Prototype Object
Please feel free to ask me about any of this post. Enjoy.