是否可以拥有以下脚本块的多个实例,每个实例都有其唯一的变量值(但变量名称相同),并在运行此块后面的外部js时访问它们?
<script type="text/javascript">
/*<![CDATA[*/
my_key = "1a";
my_time = new Date().getTime();
my_custom_params = {};
/*]]>*/
</script>
<script type='text/javascript' src='run.js?id=1901'></script>
答案 0 :(得分:1)
没有。 script
个元素都存在于同一个“范围”中,并且该范围默认为“全局”,因此如果第二次声明/分配相同的变量,它将覆盖之前的值。
这就是我们想要避免“全局”范围的原因,我们通过创建带有函数的代码模块来实现这一目的。
只要从外部脚本访问变量,这是可能的,前提是外部脚本在声明和初始化变量之后执行,并且外部脚本可以访问其他变量的范围。
鉴于我们想要避开全局范围,您必须通过较小的范围(例如函数或对象)使这些变量可用。
<script>
var my_key = "1a";
var my_time = new Date().getTime();
var my_custom_params = {};
console.log(my_key);
console.log(my_time);
console.log(my_custom_params);
</script>
<script>
// These assignments will overwrite the earlier values:
my_key = "2b";
my_time = new Date().getTime();
my_custom_params = {other:"value"};
console.log(my_key);
console.log(my_time);
console.log(my_custom_params);
</script>
以下是避免全局范围但将变量提供给其他代码的方法示例:
<script>
(function(){
var my_key = "1a";
var my_time = new Date().getTime();
var my_custom_params = {};
// Make a dummy object, give it new properties and assign the private values to them
var dummy = {};
dummy.my_key = my_key;
dummy.my_time = my_time;
dummy.my_custom_params = my_custom_params;
// Expose the dummy object via a custom property on the global object
window.myCustomNamespace = dummy;
}());
</script>
<script>
// As long as this code executes after the above code, it doesn't matter if this code
// is in an external file or not.
// We can now access the data via the custom namespace:
console.log(window.myCustomNamespace.my_key);
console.log(window.myCustomNamespace.my_time);
console.log(window.myCustomNamespace.my_custom_params);
</script>
答案 1 :(得分:1)
要完成Scott的答案,请注意立即调用函数表达式(IIFE)只是其中一个选项。重要的是创建一个孤立的范围,以避免全球范围内的冲突。因此,感谢ES6,你也可以这样做:
<script>
{
let my_key = "1a";
let my_time = new Date().getTime();
let my_custom_params = {foo: 'Foo'};
console.log(my_key, my_time, my_custom_params);
}
</script>
<script>
{
let my_key = "1b";
let my_time = new Date().getTime();
let my_custom_params = {bar: 'Bar'};
console.log(my_key, my_time, my_custom_params);
}
</script>
答案 2 :(得分:1)
它很复杂,因为所有这些变量都在同一个全局范围内,但是当每个声明脚本后面直接跟着使用这些值的脚本时,它确实可能:
<script type="text/javascript">
my_key = "1a";
my_time = new Date().getTime();
my_custom_params = {};
</script>
<script type="text/javascript">
(function(key, time, params) {
// scoped variables only available in here
// won't be overwritten by the following script
}(my_key, my_time, my_custom_params));
</script>
<script type="text/javascript">
// overwrites the variables
my_key = "2b";
my_time = new Date().getTime();
my_custom_params = {};
</script>
<script type="text/javascript">
{
const locals = {
key: my_key,
time: my_time,
params: my_custom_params
};
// locals.… available only in this scope
// the object won't be overwritten or mutated by following scripts
}
</script>
…
您需要在下次覆盖之前评估全局变量,并将其值存储在安全的地方。
当然,这仍然是一种可怕的做法。你真的应该让每个脚本创建一个唯一的命名空间(对象)并将其值放在那里。