【问题标题】:Weird behavior like dynamic scoping in Javascript奇怪的行为,如 Javascript 中的动态范围
【发布时间】:2018-03-23 13:48:03
【问题描述】:

我有以下测试代码:

// Generated by CoffeeScript 2.2.3
(function() {
  var t, test;

  test = function() {
    var dynamic_scoped_function, nested_function, vairable_function;
    dynamic_scoped_function = function() {
      return console.log(`variable function value: ${vairable_function()}`);
    };
    vairable_function = function() {
      return "not in nested function";
    };
    nested_function = function() {
      var nested_caller;
      vairable_function = function() {
        return "in nested function";
      };
      nested_caller = function() {
        console.log("calling dynamic scoped function from nested...");
        return dynamic_scoped_function();
      };
      return {
        vairable_function,
        nested_caller
      };
    };
    return {
      dynamic_scoped_function,
      nested_function
    };
  };

  t = test();

  t.dynamic_scoped_function();

  t.nested_function().nested_caller();

}).call(this);

用node.js运行的结果是

variable function value: not in nested function
calling dynamic scoped function from nested...
variable function value: in nested function

似乎当名称variable_functiondynamic_scoped_function 中解析时,它取决于调用堆栈,但没有像我期望的那样静态解析到外部。

在我看来,这种行为很愚蠢,因为我无法预见dynamic_scoped_function 会在哪里被调用。这种语言设计成这样吗?还是我只是误解了什么?

感谢您的帮助。

【问题讨论】:

  • 这是令人费解的代码,任何人都不应该编写代码,但可以满足我的期望......
  • 所以当你在一个块之外定义了一个变量并且你在那个块内设置了它会得到那个值的值时,你会感到惊讶吗?
  • @Cowsay 当您出错时,程序无法按预期运行。
  • @Cowsay 比您使用要求定义和使用所有变量的 linter 或使用 const 无法重新定义事物并会导致错误的情况。
  • 这是使用function funcname(){} 而不是funcname = function(){} 的好理由

标签: javascript scope dynamic-scope


【解决方案1】:

一旦您执行nested_function,它就会为vairable_function [原文如此] 变量分配一个新函数。该变量仍然是相同的,但它现在拥有一个新值。这具有相同的效果:

t.nested_function();          // replaces vairable_function
t.dynamic_scoped_function();  // accesses the redefined vairable_function

或大大简化:

var foo = 'bar';
console.log(foo);
foo = 'baz';
console.log(foo);

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2017-09-12
    相关资源
    最近更新 更多