在John Resig的Simple "Class" Instantiation in Javascript帖子中,他说:
" ...如果您有一个经常访问的功能(返回一个对象),您希望人们与之交互,那么将对象属性放在原型链中对您有利并实例化它。这是代码:"
// Very fast
function User(){}
User.prototype = { /* Lots of properties ... */ };
// Very slow
function User(){
return { /* Lots of properties */ };
}
我想将此应用于以下函数(恰好存在于"类"声明中)
//...
this.get_subscription = function(args)
{
return {
property_one: "value",
property_two: {
sub_prop: args.something
}
}
}
但不知道在哪里放args。如果我做
this.get_subscription = function(args) {}
this.get_subscription.prototype = {
property_one: "value"
//...
}
它会说args是未定义的。我尝试了几种变体,但都没有。我应该如何正确地做到这一点,并没有将args放在父类的范围内?
答案 0 :(得分:3)
你似乎误解了prototype
的观点。 Prototype包含应该对象的所有实例共有的方法和字段。因此,如果property_two
基于传递给构造函数的args
,则不属于原型!
毕竟,在这段代码中
this.get_subscription = function(args) {}
this.get_subscription.prototype = {
property_one: "value"
//...
}
首先,创建函数get_subscription
,然后将其原型设置为对象文字。在调用构造函数之前没有args
,因此在原型中对args
执行某些操作是没有意义的。
因此,您通常的javascript对象应该看起来像这个例子 - 2D点类。
function Point(x, y) {
/* In constructor:
* initialize fields that are related to the constructor parameters
* and are different for different instances
*/
this.x = x;
this.y = y;
}
// in prototype, define fields that are common to all instances
Point.prototype.RED = '#FF0000';
/* in prototype, also define the methods; as they can use the "this" keyword,
* they can reference their own instance, so you don't have to include them
* in each instance manually
*/
Point.prototype.toString = function() { return '[' + this.x + ', ' + this.y + ']'; };
答案 1 :(得分:1)
是的,这就是“所有原型”的缺点:-idea:你无法访问构造函数参数 - 它们只能在里面函数体中使用(exets你放他们在那里成为公共财产)。需要使用它们的所有东西 not 都属于原型;你只会在原型上填充“默认属性”(通常是所有实例共有的方法)。
我认为你在这里不需要那个。该模式仅对真正的构造函数有用,你似乎没有这里(我当时希望this.Subscription
)。此外,承诺的“性能提升”可以忽略不计。
如果你真的想在这里使用它,那就是:
function Class() {
this.Subscription = function(args) {
this.propertyTwo = {
subprop: args.something
};
};
this.Subscription.prototype = {
property_one: "value",
property_two: {}
};
}
// a method callable without the "new" operator:
Class.prototype.get_subscription = function(args) {
return new this.Subscription(args);
}
用法:
var object = new Class();
var sub = new object.Subscription();
var sub2 = new object.Subscription();
// the promised boost is less memory usage for:
sub.propertyOne === object.Subscription.prototype.propertyOne === sub2.propertyOne;
当您尝试在propertyTwo
- 对象上设置/更改/删除属性时,还要关注Crockford's Prototypal inheritance - Issues with nested objects。