从多个内联javascript块中读取变量

时间:2017-05-15 23:51:37

标签: javascript scope

是否可以拥有以下脚本块的多个实例,每个实例都有其唯一的变量值(但变量名称相同),并在运行此块后面的外部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>

3 个答案:

答案 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>
…

您需要在下次覆盖之前评估全局变量,并将其值存储在安全的地方。

当然,这仍然是一种可怕的做法。你真的应该让每个脚本创建一个唯一的命名空间(对象)并将其值放在那里。