我有一个全局变量NS,我可以从控制台访问它:
NS.some_func();
使用名为extendSafe()
some_scope.extendSafe = function (o1, o2) {
var key;
for (key in o2) {
if (o2.hasOwnProperty(key) && o1.hasOwnProperty(key)) {
throw "naming collision: " + key;
}
o1[key] = o2[key];
}
return o1;
};
通过设置名为$P
的公共范围,然后在定义所有$ P方法后复制到全局范围NS
,可以使用此方法。
我想这样做,所以我可以验证我没有写过任何属性。
这很有效,直到我尝试将局部变量保存到$P
以便以后复制到NS
。因为解释器不知道$ P将“释放”到窗口范围,所以它不知道保持局部变量是活动的。所以我不能使用我的safeExtend方法。
我通过直接复制验证了这是问题:
NS.local = local;
我现在可以从控制台访问NS.local。
但是如果我按照我的意愿将其复制出来:
$P.local = local;
extendSafe(NS, $P);
本地变量不可用。
如何安全地释放它,即使用safeExtend()
?
代码段
问题被评为
// hacked needs a fix
$P.machine = function (obj) {
var pipe,
data_send,
ajax_type,
wait_animation,
set;
wait_animation = document.getElementById('wait_animation');
set = false;
pipe = NS.makePipe(obj);
if ($R.Parsel[pipe.model] === undefined) {
return;
}
time('start');
if ($R.Parsel[pipe.model].hasOwnProperty("pre")) {
pipe = $R.Parsel[pipe.model].pre(pipe);
} else {
return;
}
if (pipe.form_data) {
ajax_type = 'multi';
var form_data = pipe.form_data;
delete pipe.form_data;
form_data.append("pipe", JSON.stringify(pipe));
data_send = form_data;
} else {
ajax_type = 'post';
data_send = 'pipe=' + encodeURIComponent(JSON.stringify(pipe));
}
if (pipe.state === true) {
time('middle');
if (wait_animation) {
set = true;
wait_animation.style.opacity = 1;
}
NS.ajax({
type: ajax_type,
url: NS.Reg.get('path') + NS.Reg.get('path_ajax'),
data: data_send,
callback: function (pipe_string_receive) {
var pass_prefix = pipe_string_receive.slice(0, 3),
times;
if (wait_animation && set) {
wait_animation.style.opacity = 0;
}
if (pass_prefix === '|D|') {
NS.log('|DEBUG| ' + pipe_string_receive.slice(3));
} else if (pass_prefix === '|A|') {
time('middle');
pipe = JSON.parse(pipe_string_receive.slice(3));
if ($R.Parsel[pipe.model].hasOwnProperty("post")) {
pipe = $R.Parsel[pipe.model].post(pipe);
times = time('finish');
pipe.time.pre = times[0];
pipe.time.transit = times[1];
pipe.time.post = times[2];
// works but hacked needs a fix
NS.last = pipe;
// will not exendSafe()
$P.last = pipe;
} else {
return;
}
} else {
throw "<No 'A' or 'D'>" + pipe_string_receive;
}
}
});
}
};
答案 0 :(得分:1)
我看到你已经解决了这个问题,但我觉得你有一些关于JavaScript的误解:
这很有效,直到我尝试将局部变量保存到$ P以便以后复制到NS。因为解释器不知道$ P将“释放”到窗口范围,所以它不知道保持局部变量是活动的。所以我不能使用我的safeExtend方法。
我通过直接复制验证了这是问题:
NS.local = local;
我现在可以从控制台访问NS.local。
但是如果我按照我的意愿将其复制出来:
$P.local = local; extendSafe(NS, $P);
本地变量不可用。
如何安全地释放它,即使用
safeExtend()?
这没有意义。 JavaScript非常擅长跟踪对象的引用。如果有任何对象的引用,它将不会垃圾收集该对象。我不知道“将对象释放到窗口范围”意味着什么。实际上没有任何这样的概念,只有对象和对它们的引用。
我尝试查看原始代码,但那里有很多代码与问题无关。如果你把它简化为一个最小的测试用例,我敢打赌一个更简单的解决方案就会变得明显。
我确实在上面的小片段中看到了一个问题。您已将extendSafe()
功能定义为some_scope.extendSafe()
,但此处您通过普通extendSafe()
来电呼叫它,而不是some_scope
的引用。它真的调用了函数吗?在较小的例子中,这只是一个错字吗?
当然,如果你很高兴能找到解决方案并希望继续前进,那就太可以理解了!我有一种强烈的感觉,这里有额外的代码,你不需要。