【问题标题】:Javascript how to avoid variable name conflicts in Functions?Javascript如何避免函数中的变量名冲突?
【发布时间】:2020-03-05 19:50:13
【问题描述】:

我在使用 dropzone 时发现了一些奇怪的东西:

这是我的掉落:

<script type="text/javascript">

var CountFiles = 0;


$(document).ready(function () {

    Dropzone.autoDiscover = false;

    var new_file;

    const Drop1 = new Dropzone("div#myPrincipalDropzone", {
        url: "/Article/UploadFiles",

        paramName: "file",
        maxFiles: 1,
        maxFilesize: 1200,
        maxFileHeight: 840,
        maxFileWidth: 840,
        acceptedFiles: ".png,.jpg",
        addRemoveLinks: true,
        parallelUploads: 1,
        renameFile: function (file) {
            let newname = new Date().getTime() + '_';
            console.log("Nombre en RenameFile:" + newname);
            file.name = newname;
            console.log("Asigno al file el nombre:" + file.name);
            new_file = new File([file], newname + file.name);
            console.log(new_file.name);
            return new_file;
        },

        init: function (new_file) {

我注意到我在 return 语句中的变量“new_file”的值为“123847123_Filename.ext” 但是,当我尝试使用该变量调用另一个方法或函数时,我收到 new_file 作为“Filename.ext”,失去了我的旧值。

在 google 上搜索我发现 javascript 与嵌套函数之间的名称参数有一些冲突。

有办法解决这个问题吗?我需要在多个函数/方法调用中使用我的旧值。

【问题讨论】:

  • 没有new_value 可供两者使用,而只是将其设为本地?为什么你还需要它?
  • 不要在超出实际需要的范围内定义变量。永远不要使用var(任何最新的 linter 都应该默认强制执行此操作)。避免在其他函数中定义复杂的函数(这个可能会引起争议,但它往往会导致这类泄漏范围问题)。
  • 我知道,但这次是必需的,我需要使用函数“renameFile”使用日期时间将每个文件重命名为“unique_id”。稍后我需要使用该参数来使用 Dropozone 方法验证文件,就像大小或删除等一样。
  • @DanKanze - 这种推理方式同样适用于goto。一个不犯错误的程序员可以使用varlet 以同样的效率,但var 范围错误是一个极端的common source of avoidable errorsletconst 是块作用域,而不是函数作用域。如果你想将变量移动到块的顶部,很好,但是在它们的块范围之外定义它们也会导致很多潜在的错误。但是,这些是指导方针。总会有需要偏离“最佳实践”的情况。
  • @DanKanze "如果一个程序运行它就会运行" So does a burning bus

标签: javascript dropzone


【解决方案1】:

编辑 1:纠正上下文和范围之间的混淆

编辑 2:对 范围链 的引用并删除“参数”范围,因为没有这样的东西

嗯,之所以会这样,是因为Closures

一个函数可以访问两件事:

  1. 局部范围:函数定义内的变量接收的参数。如果已定义,它们将用于代替父作用域中可用的变量。
  2. 父范围:变量定义在函数最初定义的范围内(通常被错误地称为“全局”上下文)。见Scope chains*

* 一个函数的作用域对于它内部定义的函数来说是全局的,因此父函数的作用域包括所有上父函数的作用域,直到你到达全局作用域。

这是一个 sn-p,您可以使用它来查看许多不同案例中的一些案例,这些案例展示了 context 在变量“名称”方面的作用:


    const x = 'GLOBAL X VALUE';
    function A() {
      // A is referring to X within its own context
      console.log(`The value of x in A is => ${this.x}`);
      console.log(`The value of y in A is => ${this.y}`);
    }

    function B() {
      // B is referring to x within the context in which it was defined
      console.log(`The value of x in B is => ${x}`);
    }

    function C() {
      // C is referring to x within the context in which it was defined
      // That's why it also prints the value of the "global" context even if you
      // call it within a context that has a value with the same name
      console.log(`The value of x in C is => ${x}`);
    }

    function D(x) {
      console.log(`The value of x in D is => ${x}`);
      C();
    }

    function F() {
      // A is going to have access to the context of F, but it will not have access
      // to the global context
      this.y = "the other value";
      A.bind(this)();
      console.log(`The value of x in F is => ${x}`);
    }

    function G(x) {
      this.x = "HMMMM";
      console.log(`The value of local x in G is => ${this.x}`);
      console.log(`The value of param x in G is => ${x}`);
    }

    A(); // the value of x and y will be undefined
    B(); // the value of x will be the global context
    D("Parameter x value"); // the value of x will be the one passed as a parameter
    F();
    G("Parameter x value"); // the parameter and the local context are two different things

this* it's dangerous to go alone, take this documentation

【讨论】:

  • 1.您似乎没有引用this 关键字2 的“参数上下文”。一个函数可以访问三个以上的作用域。或更少,取决于它的定义位置。在您进入全局范围之前,它将是本地范围、父范围和所有其他父范围。但只有一个上下文 - this
  • 1.如果你运行它,G 将打印两个不同的值,因为它有一个x,它是一个参数,一个是在其上下文中定义的。 2. 你是对的,我想我可能歪曲了 javascript 在定义函数时所做的一些非常重要的绑定机制。我们需要更多示例来演示它如何处理 => a function defined inside of G that uses x 之类的东西
  • xthis.x 一直是不同的。一个是参数属于范围,另一个是属性,属于上下文。以任何方式将两者等同起来都是一种误导——除了名称之外,它们之间没有任何共同点,即使这也是一个意外。机制完全不同。
  • 我明白你现在的意思了,我指的是范围和上下文,就好像它们是同一件事一样,我会尝试编辑我的答案来纠正这个问题。
  • 为了进一步混淆......在某些情况下,this 是对 window 的引用,可以使用在全局范围内定义的 var 变量填充。所以在技术上有一个var x,以后可以作为this.x访问。避免var的另一个原因。
猜你喜欢
  • 2016-03-27
  • 2021-04-15
  • 2013-03-09
  • 2013-03-17
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2014-03-12
  • 2015-03-21
相关资源
最近更新 更多