[英]About javascript prototype
A strange problems about javascript prototype : 有关javascript原型的一个奇怪的问题:
(function(w){
if(!w)
return;
var TestJS = function(){
};
TestJS.prototype = {
data:{},
initData:function(){
this.data={
val_name_1 : 1,
val_name_2 : 2,
val_name_3 : "hello-3"
};
console.log(this.data);
return this;
},
TestChildJS:{
initChild:function(){
console.log(TestJS);
console.log(TestJS.data);
console.log(new TestJS().data.val_name_1);
console.log(TestJS.data.val_name_1);
}
}
};
window.TestJS = new TestJS();
})(window);
why 'TestChildJS' can not get 'val_name_1'? 为什么'TestChildJS'无法获得'val_name_1'?
TestJS.initData();
console.log(TestJS.TestChildJS.initChild());
so I have to write my code like that: 所以我必须这样写我的代码:
(function(w){
if(!w)
return;
var TestJS = function(){
};
TestJS.prototype = {
data:{},
initData:function(){
this.data={
val_name_1 : 1,
val_name_2 : 2,
val_name_3 : "hello-3"
};
console.log(this.data);
this.TestChildJS.initParentData(this);
return this;
},
TestChildJS:{
parentData:{},
initParentData:function(parent){
this.parentData = parent.data;
return this;
},
initChild:function(){
console.log(this.parentData);
}
}
};
window.TestJS = new TestJS();
})(window);
How to use the first way can get the content of the second way? 如何使用第一种方式可以获得第二种方式的内容?
why 'TestChildJS' can not get 'val_name_1'?
为什么'TestChildJS'无法获得'val_name_1'?
when: 什么时候:
TestJS.initData();
is run, it adds a data property to the TestJS object (the one assigned by window.TestJS = new TestJS()
). 运行时,它将数据属性添加到TestJS对象(
window.TestJS = new TestJS()
分配的window.TestJS = new TestJS()
)。 That property isn't inherited by any other object. 该属性不会被任何其他对象继承。
When: 什么时候:
console.log(new TestJS().data.val_name_1);
is run, the object returned by new TestJS()
has not had it's initData method called yet, so it doesn't have a data property and it doesn't inherit it from the constructor (because the property is directly on the constructor itself, not its prototype). 运行时,由
new TestJS()
返回的对象尚未调用过initData方法,因此它没有数据属性,也不会从构造函数继承它(因为该属性直接在构造函数本身上,而不是其原型)。
Note also that assigning a new object to this.data creates a property directly on the instance, so adding to this.data is modifying the instance's data object, not the one on the constructor's prototype. 还要注意,为this.data分配一个新对象会直接在实例上创建一个属性,因此添加到this.data就是在修改实例的数据对象,而不是构造函数原型上的对象。
The patterns in your code (especially the second one) seem unnecessarily convoluted. 代码中的模式(尤其是第二个模式)似乎不必要地复杂。
It has to do with the scope of the IIFE. 它与IIFE的范围有关。 A variable declared inside a closure shadows any outer variable with the same name.
在闭包内部声明的变量会遮盖任何同名外部变量。 Since after the IIFE executes you no longer have access to its scope, TempJS inside it will always be a function constructor -- not an instantiated object.
由于执行IIFE之后,您将无法再访问其作用域,因此其中的TempJS将始终是函数构造函数-而不是实例化的对象。
Consider this example: 考虑以下示例:
var i;
var func = (function(){
i = 1;
return function() {
console.log(i)
};
})();
func(i); // 1
i = 2;
func(i); // 2
If I re-declare the i
variable inside the closure, look what happens: 如果我在闭包内部重新声明
i
变量,请看会发生什么:
var i = 1;
var func = (function(){
var i = 1;
return function() {
console.log(i)
};
})();
func(i); // 1
i = 2;
func(i); // 1
So one solution to your problem would be to declare TestJS
once before the IIFE. 因此,解决您的问题的一种方法是在
TestJS
之前声明一次TestJS。
var TestJS;
(function(w){
if(!w)
return;
TestJS = function(){
};
// ...
TestChildJS:{
initChild:function(){
console.log(TestJS.data.val_name_1);
}
// ...
window.TestJS = new TestJS();
})(window);
TestJS.initData();
console.log(TestJS.TestChildJS.initChild()); // 1
Notice that I removed console.log(new TestJS().data.val_name_1);
注意,我删除了
console.log(new TestJS().data.val_name_1);
. 。
TestJS
is no longer a constructor function, so that line will throw. TestJS
不再是构造函数,因此该行将抛出。
Another solution is to assign the empty function expression to window.TestJS
inside the closure, instead of var TestJS
. 另一种解决方案是将空函数表达式分配给闭包内的
window.TestJS
,而不是var TestJS
。 Doing so will not create a local TestJS
name and will therefore prevent the ambiguity. 这样做不会创建本地
TestJS
名称,因此可以避免歧义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.