我想在Javascript中创建相同原型的2个不同“实例”。请注意,这里的“实例”一词并不是指“实例化的类”,而是指两个不同的类实例(例如,一个特定的类以Java术语从2个不同的类加载器加载)。
假设我有这个对象:
var protoObj = {
prop: "",
method: function () {
// do stuffz
}
}
protoObj.method.staticProperty = 0;
function childObj (prop) {
this.prop = prop;
}
childObj.prototype = protoObj;
var child1 = new childObj("First Child");
var child2 = new childObj("Second Child");
console.log("Prop:", child1.prop); //prints "Prop: First Child"
console.log("Prop:", child2.prop); //prints "Prop1: Second Child"
child1.method.staticProperty = 1;
child2.method.staticProperty = 2;
console.log("Child1 Static:", child1.method.staticProperty); //prints "Child1 Static: 2" <-- I wanted this to be 1. I want each instance to have its own "parent"
console.log("Child2 Static:", child2.method.staticProperty); //prints "Child2 Static: 2"
我的目标是让child1.method.staticProperty
与child2.method.staticProperty
您可能会问为什么需要这样做?在函数属性中存储状态确实是错误的,但上面的代码来自Typescript编译器,它编译“类静态”作为JavaScript构造函数的属性。我需要的是为同一个类名设置不同的静态值。
请注意,在我的情况下,protoObj
本质上是一个javascript applicationApi(一个20K行文件),我们的目标是能够在只加载一次库时创建应用程序的2个不同实例。
答案 0 :(得分:0)
静态属性是类级属性,静态属性的更改将反映给每个子级相同。 正如您在打印非静态变量时所看到的那样,答案是正确的,但是当您打印静态变量时,输出具有相同的值。 ** child1,child2是不同的实例,但具有相同的静态
protoObj.prototype.childObj = function() {
console.log("Downloading protoObj ...");
}
试试这个....当创建一个新的protoObj对象时,这个新对象将从构造函数的原型中“继承”childObj方法,并可以使用。
答案 1 :(得分:0)
您需要为每个静态实例&#39;实例化静态属性。
这利用了javascripts的动态性,实际上用自身的实例覆盖了.method。
您将最终覆盖对基础protoObj.method的引用,并为每个子对象添加一个新实例。我相信这是你在问题中试图提出的问题。
var protoObj = {
prop: "",
method: function () {
// do stuffz
}
}
protoObj.method.staticProperty = 0;
function childObj (prop) {
this.prop = prop;
}
childObj.prototype = protoObj;
var child1 = new childObj("First Child");
var child2 = new childObj("Second Child");
var child3 = new childObj("Third Child");
console.log("Prop:", child1.prop); //prints "Prop: First Child"
console.log("Prop:", child2.prop); //prints "Prop: Second Child"
console.log("Prop:", child3.prop); //prints "Prop: Second Child"
child1.method = new child1.method();
child1.method.staticProperty = 1;
child2.method = new child2.method();
child2.method.staticProperty = 2;
console.log("Child1 Static:", child1.method.staticProperty); //prints "Child1 Static: 2" <-- I wanted this to be 1. I want each instance to have its own "parent"
console.log("Child2 Static:", child2.method.staticProperty);
console.log("Child3 Static:", child3.method.staticProperty);
答案 2 :(得分:0)
执行此操作的唯一方法是每次在构造函数中创建method
的新实例。基本上是将method
移出原型并进入构造函数:
var protoObj = {
// some share stuff
}
function childObj (prop) {
// non-shared stuff:
this.prop = prop;
this.method = function () {
// do stuffz
}
this.method.staticProperty = 0;
}
childObj.prototype = protoObj;
我将个别事物放在哪里的个人规则:如果属性是字符串或数字或布尔值然后将其放在原型中,其他所有内容都将它放在构造函数中。这是因为原型是由浅拷贝继承的。它不一定是函数,如果你的原型中有对象,你会遇到麻烦:
function Foo () {}
Foo.prototype = {
a: "no problem",
b: {
x: "problem"
}
}
var i = new Foo();
var j = new Foo();
var k = new Foo();
i.a += " 1";
j.a += " 2";
k.a += " 3";
console.log(i.a , j.a , k.a); // no problem 1, 2, 3
i.b.x += " 1";
j.b.x += " 2";
k.b = { x: "problem 3" };
console.log(i.b.x , j.b.x , k.b.x); // problem 2, 2, 3
如果您按照规则仅使用原型来处理字符串,数字和布尔值的属性,那么您就不会遇到麻烦:
function Foo () {
this.b = {
x: "no problem"
};
}
Foo.prototype = {
a: "no problem"
}
i.b.x += " 1";
j.b.x += " 2";
k.b = { x: "no problem 3" };
console.log(i.b.x , j.b.x , k.b.x); // no problem 1, 2, 3
答案 3 :(得分:0)
我的目标是
的值不同child1.method.staticProperty
与child2.method.staticProperty
只有在两种方法不同的情况下才有可能,所以你的对象继承了两个原型对象 - 如果没有创建两个protoObj
或者克隆它就不可能实现,你说你不会这样做。 ; t想要。
请注意,在我的情况下,
protoObj
本质上是一个javascript applicationApi(一个20K行文件),我们的目标是能够创建2个不同的应用程序实例
包含脚本文件两次以执行两次并创建两个不同的对象:
<script type="text/javascript" src="applicationApi.js"></script>
<script type="text/javascript">
console.assert(childObj.prototype == protoObj);
var firstInstance = childObj;
protoObj.method.staticProperty = 1;
</script>
<script type="text/javascript" src="applicationApi.js"></script>
<script type="text/javascript">
console.assert(childObj.prototype == protoObj);
var secondInstance = childObj;
protoObj.method.staticProperty = 2;
</script>
<script type="text/javascript">
console.log(new firstInstance);
console.log(new secondInstance);
console.log(firstInstance !== secondInstance);
</script>
但请注意,需要这样做表明api库的设计存在错误。
...只加载一次库。
只需发送相应的缓存标头即可隐式完成。