Javascript 是否可以将非共享变量添加到原型中?

Javascript 是否可以将非共享变量添加到原型中?,javascript,Javascript,我正在构建一个功能,用一些常用的功能来改进我的一些原型 我还想通过这个机制添加特定于对象实例的变量,类似于: function give_weird_container(target) { target.<somehow instance specific, not prototype>.underlying_container = []; target.prototype.container_func = function(x, y, z) { re

我正在构建一个功能,用一些常用的功能来改进我的一些原型

我还想通过这个机制添加特定于对象实例的变量,类似于:

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);
在构造函数中

在give_-weird_-container函数的范围内,这可能吗

是否可以将非共享变量添加到原型中

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

但是,您可以向原型添加一个getter,该getter将创建一个实例特定的属性(如果它不存在)

例如:

Object.defineProperty(target.prototype, 'underlying_container', {
  get: function() {
    if (!this._underlying_container) {
      this._underlying_container = [];
    }
    return this._underlying_container;
  },
});
getter是共享的,但返回的值是每个实例的

如果您不喜欢每次访问
this.undernative_container
时都执行getter,那么在第一次调用prototype属性时,您可以将其替换为实例属性:

Object.defineProperty(target.prototype, 'underlying_container', {
  get: function() {
    Object.defineProperty(this, 'underlying_container', {value: []});
    return this. underlying_container;
  },
});
Object.defineProperty(这是“底层容器”{value:[]})
将在实例上创建一个同名的新属性,从而隐藏在原型上定义的getter


为了接受@4castle的建议,如果可以直接对实例进行变异,那么您可以改为执行类似的操作,这有点不那么“神奇”:


您可以给
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);

你是说像<代码>target.undernative_container=[]
以某种方式特定于实例
但函数中没有实例???@ankitbug94是的,属性将添加到所有新的instances@ankitbug94那是不可能的sense@user81993现在我知道你想要非共享数组了。我认为您只需要特定实例上的变量。我的错误是,使用每个实例特有的
会更清楚这感觉像是为了做一些他们不应该做的事情而进行的黑客攻击。基本继承似乎是他们所需要的。@4castle不,他不需要基本原型继承,因为我不确定,但可能是OP不想更改目标(my_class1)内的内容@4castle:Inheritation仅在可以更改类定义的情况下才起作用,在这种情况下,这可能不可能或不需要。对我来说,OP似乎需要一些类似mixins的东西。ankitbug94是正确的,我希望将我必须维护的代码保持在最低限度,或者至少不在整个项目中传播。@ankitbug94原型继承可能有些过分。听起来他们需要创建一个包装函数来设置他们想要的字段,然后调用构造函数。那么传递给构造函数的参数呢?此外,这将使
var foo=new my_class1();log(my_class1的foo实例)返回
false
。可能不重要,但值得指出。或者被替换的
my_class1
是否在不使用
new
的情况下调用?@Felix返回的函数可以使用
new
或不使用
new
进行调用,其行为相同。据我所知,
instanceof
操作符将返回
true
。需要指定参数。“instanceof运算符将返回true(据我所知)。”如果使用
new
调用函数,则不会返回true(请参阅)。“需要指定参数”,在这种情况下,不可能将其应用于不同的类。同样,这不一定是一件坏事,但可能值得指出。@FelixKling因为类正在包装,所以不带new也将返回false,因为
my_class1
是从
give_Ordy_容器返回的新匿名函数
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);
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);