在 Javascript 中创建同一原型的不同实例
Creating different instance of the same prototype in Javascript
我想在 Java 脚本中为同一原型创建 2 个不同的 "instances"。请注意,这里的 "instances" 一词不是指 "instantiated classes",而是指 2 个不同的 class 实例(一个特定的 class 已从 2 个不同的 class 加载器加载例如 Java 术语)。
假设我有这个对象:
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 编译器,它将 "Class Statics" 编译为 JavaScript 构造函数的属性。我需要的是为相同的 class 名称设置不同的静态值。
请注意,在我的例子中,protoObj
本质上是一个 javascript applicationApi(一个 20K 行的文件),我们的目标是能够在加载库时创建 2 个不同的应用程序实例只有一次。
static 属性 是 class 级别 属性 并且 static 属性 的变化将反映到每个 child 相同。
正如您在打印非静态变量时看到的那样,答案是正确的,但是当您打印静态变量时,输出具有相同的值。 **child1,child2 是不同的实例,但具有相同的静态
protoObj.prototype.childObj = function() {
console.log("Downloading protoObj ...");
}
试试这个....当创建一个新的 protoObj object 时,这个新的 object 将从构造函数的原型中“继承” childObj 方法,并且可以使用了。
您需要为每个 'static instance' 实例化静态 属性。
这利用了 javascript 的动态特性,实际上用它自己的一个实例覆盖了 .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);
唯一的方法是每次在构造函数中创建一个 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
My goal is for child1.method.staticProperty
to have a different value from child2.method.staticProperty
这只有在两种方法不同时才有可能,因此您的 objects 继承自两个原型 objects - 如果不创建两个 protoObj
或克隆它,你说你不想。
Note that in my case the protoObj
is essentially a javascript applicationApi (a 20K line file) and our goal is to be able to create 2 distinct instances of he application
两次包含脚本文件以执行两次并创建两个不同的 objects:
<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 库的设计存在错误。
…while loading the library only once.
只需发送适当的缓存 headers 即可隐式完成。
我想在 Java 脚本中为同一原型创建 2 个不同的 "instances"。请注意,这里的 "instances" 一词不是指 "instantiated classes",而是指 2 个不同的 class 实例(一个特定的 class 已从 2 个不同的 class 加载器加载例如 Java 术语)。
假设我有这个对象:
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 编译器,它将 "Class Statics" 编译为 JavaScript 构造函数的属性。我需要的是为相同的 class 名称设置不同的静态值。
请注意,在我的例子中,protoObj
本质上是一个 javascript applicationApi(一个 20K 行的文件),我们的目标是能够在加载库时创建 2 个不同的应用程序实例只有一次。
static 属性 是 class 级别 属性 并且 static 属性 的变化将反映到每个 child 相同。 正如您在打印非静态变量时看到的那样,答案是正确的,但是当您打印静态变量时,输出具有相同的值。 **child1,child2 是不同的实例,但具有相同的静态
protoObj.prototype.childObj = function() {
console.log("Downloading protoObj ...");
}
试试这个....当创建一个新的 protoObj object 时,这个新的 object 将从构造函数的原型中“继承” childObj 方法,并且可以使用了。
您需要为每个 'static instance' 实例化静态 属性。
这利用了 javascript 的动态特性,实际上用它自己的一个实例覆盖了 .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);
唯一的方法是每次在构造函数中创建一个 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
My goal is for
child1.method.staticProperty
to have a different value fromchild2.method.staticProperty
这只有在两种方法不同时才有可能,因此您的 objects 继承自两个原型 objects - 如果不创建两个 protoObj
或克隆它,你说你不想。
Note that in my case the
protoObj
is essentially a javascript applicationApi (a 20K line file) and our goal is to be able to create 2 distinct instances of he application
两次包含脚本文件以执行两次并创建两个不同的 objects:
<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 库的设计存在错误。
…while loading the library only once.
只需发送适当的缓存 headers 即可隐式完成。