Javascript:使用性能参数对函数进行原型设计

时间:2012-05-02 23:16:14

标签: javascript optimization prototype

在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放在父类的范围内?

2 个答案:

答案 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