在 Javascript 中使用 .prototype 的原因
使用 .prototype 而不是在对象本身内部声明函数和成员的技术原因是什么?用代码示例来解释是最简单的。
使用以下优点:
RobsObject = function(data){
this.instanceID = data.instanceID;
this._formButton = document.getElementById('formSubmit_' + this.instanceID);
if(this._formButton)
{
//set a click listener that
//points to this._onSubmit, this._onSuccess, and this.onFailure
}
};
RobsObject.prototype = {
_onSubmit: function(type, args)
{
//make an ajax call
},
_onSuccess: function(type, args)
{
//display data on the page
},
_onFailure: function(type, args)
{
//show an alert of some kind
},
};
与在对象内部声明函数相反,例如:
RobsObject = function(data){
this.instanceID = data.instanceID;
this._formButton = document.getElementById('formSubmit_' + this.instanceID);
if(this._formButton)
{
//set a click listener that
//points to this._onSubmit, this._onSuccess, and this.onFailure
}
this._onSubmit = function(type, args)
{
//make an ajax call
}
this._onSuccess = function(type, args)
{
//display data on the page
}
this._onFailure = function(type, args)
{
//show an alert of some kind
}
};
谢谢。
编辑:正如你们中的许多人指出的那样,我在第二个代码片段中的函数应该在它们前面有“this”才能公开。所以我添加了它。只是我的一个错误。
What are the technical reasons for using .prototype instead of declaring functions and members inside the object itself. It is easiest to explain with code examples.
What are the advantages of using:
RobsObject = function(data){
this.instanceID = data.instanceID;
this._formButton = document.getElementById('formSubmit_' + this.instanceID);
if(this._formButton)
{
//set a click listener that
//points to this._onSubmit, this._onSuccess, and this.onFailure
}
};
RobsObject.prototype = {
_onSubmit: function(type, args)
{
//make an ajax call
},
_onSuccess: function(type, args)
{
//display data on the page
},
_onFailure: function(type, args)
{
//show an alert of some kind
},
};
As oppose to declaring your functions inside of the Object like:
RobsObject = function(data){
this.instanceID = data.instanceID;
this._formButton = document.getElementById('formSubmit_' + this.instanceID);
if(this._formButton)
{
//set a click listener that
//points to this._onSubmit, this._onSuccess, and this.onFailure
}
this._onSubmit = function(type, args)
{
//make an ajax call
}
this._onSuccess = function(type, args)
{
//display data on the page
}
this._onFailure = function(type, args)
{
//show an alert of some kind
}
};
Thanks.
Edit: As many of you have pointed out my functions in the second code snippet should have 'this' in front of them in order to be public. So I added it. Just a mistake on my part.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
构造函数的原型中声明的所有内容都由该构造函数的所有实例共享。如果您在构造函数中定义函数,则每个实例都会获得自己的函数副本,这会浪费内存(如果稍后比较两个实例之间的属性,则可能会导致问题)。
此外,在您的示例中,构造函数中声明的函数对于该函数的范围是私有的。它们不能作为实例上的成员方法调用。为此,您需要将它们分配给对象的属性:
Douglas Crockford 对原型继承有一篇很好的文章,绝对值得一看:JavaScript 中的原型继承。
更新:简要原型摘要
当您使用构造函数创建新对象时,该函数的
prototype
属性的值将被指定为新对象的prototype 对象。 (是的,这些名称很令人困惑!)这很像在基于类的语言中分配一个超类(但不完全是!请阅读 Crockford 的页面!)Everything declared in a constructor function's
prototype
is shared by all instances of that constructor function. If you define functions in the constructor function, then each instance gets its own copy of the function, which wastes memory (and could potentially cause problems if you compare properties between two instances later).Also, in your example the functions declared in the constructor function are private to the scope of the function. They cannot be called as member methods on instances. For that you would need to assign them to properties of the object:
Douglas Crockford has a good write-up of prototypical inheritance that is definitely worth checking out: Prototypical Inheritance in JavaScript.
UPDATE: Brief Prototype Summary
When you create a new object using a constructor function, the value of the function's
prototype
property is assigned as the new object's prototype object. (Yes, the names are confusing!) This is a lot like assigning a superclass in a class-based language (but not quite! Read Crockford's page!)答案是记忆。如果将成员放入对象本身内部,则该对象的每个实例都将包含(在内存中)所有成员。另一方面,如果您使用原型,它只存在一次,所有实例都将访问这些成员,就像它们是自己的成员一样。
The answer is memory. If you put the members inside of the object itself, then EVERY instance of that object will contain (in memory) all members. If you use prototype, on the other hand, it only exists once, and all instances will access those members as if they were their own.
在第一种情况下,使用
new RobsObject()
构造的对象具有函数_onSubmit()
、_onSuccess()
作为其属性。它们是所谓的对象的公共函数。在第二种情况下,这些函数不是 new RobsObject() 的属性。但是,它们对任何“公共”功能都是可见的(在您的情况下没有任何功能)。实际上,它们是私有函数。
但是,如果您以这种方式编写第二个片段...
结果是相同的。
这两种约定之间的一个重要区别是,在第一种方法中,您不能像在第二种方法中那样定义可以在许多公共函数之间共享的私有函数。用于定义原型的对象文字不会像函数体那样形成闭包。
例如,
myPrivate()
是一个对两个公共函数都可见的函数。In the first case, an object constructed with
new RobsObject()
has the functions_onSubmit()
,_onSuccess()
as it's properties. They are so-called the public functions of the object.In the second case, those functions are not properties of
new RobsObject()
. However, they would be visible to any of the 'public' functions (there aren't any, in your case). In effect, they are the private functions.However, if you wrote your second snippet this way...
the result is the same.
An important difference between these two conventions is that in the first method, you can't define private functions that can be shared between many public functions like you do in the second method. The Object literal used to define the prototype does not form closures like a function body.
For example,
myPrivate()
is a function that is visible to both public functions.