2016-12-14 46 views
1

我正在构建一个函数,用一些常用函数翻新我的一些原型。是否可以向原型添加一个不共享的变量?

我也想通过这个修车添加对象实例的具体变量,有点儿像:

function give_weird_container(target) { 
    target.<somehow instance specific, not prototype>.underlying_container = []; 
    target.prototype.container_func = function(x, y, z) { 
     return this.underlying_container[x + 2*y + 3*z]; 
    } 
} 

function my_class1() {} 

give_weird_container(my_class1); 

,现在当我创建my_class1的新实例,它应该有一个属性“uderlying_container”,将采取行动相同的,如果我在构造函数称为

this.underlying_container = []; 

在give_weird_container函数的限制范围内,这可能吗?

+1

:你是说? 'target.underlying_container = [];' –

+0

'不知何故特定实例'但函数中没有实例? – bugwheels94

+0

@ ankitbug94好吧,是的,该属性将被添加到所有新实例 – user81993

回答

2

是否可以向原型添加一个非共享变量?

否。原型上的所有属性都是共享的。在创建实例后,只能设置实例特定的属性

然而,您可以将getter添加到将创建实例特定属性(如果它不存在)的原型。

例如:

Object.defineProperty(target.prototype, 'underlying_container', { 
    get: function() { 
    if (!this._underlying_container) { 
     this._underlying_container = []; 
    } 
    return this._underlying_container; 
    }, 
}); 

吸气剂是共享的,但返回的值是每个实例。

如果你不喜欢,吸气,每次执行this.underlying_container被访问时的事实,你可以用一个实例属性替换它当原型属性被称为第一次:

Object.defineProperty(target.prototype, 'underlying_container', { 
    get: function() { 
    Object.defineProperty(this, 'underlying_container', {value: []}); 
    return this. underlying_container; 
    }, 
}); 

Object.defineProperty(this, 'underlying_container', {value: []});会在实例上创建一个具有相同名称的新属性,从而映射原型上定义的getter。


要拿起@ 4castle的建议,如果有可能直接发生变异的情况下,那么你可以做这样的事情,而不是,这是一个有点不那么“神奇”:

var give_weird_container = (function() { 
    function container_func(x, y, z) { 
     return this.underlying_container[x + 2*y + 3*z]; 
    }; 

    return function(target) { 
     target.underlying_container = []; 
     target.container_func = container_func; 
    }; 
}()); 

function my_class1() {} 

var instance = new my_class1(); 

give_weird_container(instance); 
+0

这感觉就像一个黑客,以做一些他们不应该做的事情。基本的继承看起来像他们需要的。 – 4castle

+0

@ 4castle不,他不需要基本的原型继承,因为我不确定,但可能是OP不想改变目标中的内容(my_class1) – bugwheels94

+0

@ 4castle:只有在可以更改类定义的情况下,这在这种情况下可能不可能或不需要。对我来说,OP似乎想要mixin。 –

1

你可以给my_class1调用构造函数,然后将字段设置一个包装函数:

function give_weird_container(target) { 
    target.prototype.container_func = function(x, y, z) { 
     return this.underlying_container[x + 2*y + 3*z]; 
    } 
    return function() { 
     var obj = new target(); 
     obj.underlying_container = []; 
     return obj; 
    } 
} 

function my_class1() {} 

my_class1 = give_weird_container(my_class1); 
+1

传递给构造函数的参数呢?此外,这将使'var foo = new my_class1(); console.log(foo instanceof my_class1);'return'false'。可能不重要,但值得指出。或者被替换的'my_class1'被调用时没有'new'? –

+0

@Felix可以使用或不使用'new'来调用返回的函数,它将表现相同。据我所知,'instanceof'运算符将返回'true'。参数需要指定。 – 4castle

+0

*“instanceof运算符会尽可能地返回true”。*如果函数是用'new'调用的(请参阅https://jsfiddle.net/bthzwphe/),则不行。 *“参数需要指定”*在这种情况下,不可能将其应用于不同的类。再次,不一定是坏事,但也许值得指出。 –

相关问题