基本的Javascript范围

时间:2016-06-03 16:33:28

标签: javascript function scope coffeescript

我想了解变量范围。为什么我无法从三明治的html属性中的Utils.delay函数中获取成分值?

CoffeeScript的:

supermarket = JSON.parse(Utils.domLoadScriptSync(URL))


cart = (ingredients) ->
  Utils.delay 5, ->
    ingredients = supermarket[i].name
    return ingredients
  return ingredients
cart()

sandwich = new Layer
  html: ingredients

透明的JavaScript:

var cart, sandwich, supermarket;

supermarket = JSON.parse(Utils.domLoadScriptSync(URL));

cart = function(ingredients) {
  Utils.delay(5, function() {
    ingredients = supermarket[i].name;
    return ingredients;
  });
  return ingredients;
};

cart();

sandwich = new Layer({
  html: ingredients
});

2 个答案:

答案 0 :(得分:3)

我将在已编译的Javascript中指出问题:

// Note that ingredients isn't declared here.
var cart, sandwich, supermarket;

supermarket = JSON.parse(Utils.domLoadScriptSync(URL));

// ingredients is actually "declared" here. It's scoped to the function as a parameter.
cart = function(ingredients) {
  // We're going to run this function *asynchronously* 5 seconds later.
  Utils.delay(5, function() {
    // Here we assign a value to the function parameter, but by this
    // point cart will have already returned its value.
    ingredients = supermarket[i].name;
    return ingredients;
  });
  // Return undefined.
  return ingredients;
};
// cart is a function that takes a parameter, but you haven't passed in anything.
// cart also returns a value, but you haven't captured the return value.
cart();

sandwich = new Layer({
  // This ingredients is an undefined variable because the other ingredients
  // is scoped to the function.
  html: ingredients
});

Utils.delay将延迟5秒,但它会异步延迟。它将为ingredients函数变量赋值,但cart函数在完成之前将返回它的值。由于ingredients的作用域是函数,因此外部作用域永远不会看到指定的ingredients值。

我的建议是解决这个问题:

  • 您无需将ingredients作为函数参数传递。你永远不会使用它。
  • cart返回您应捕获的值。
  • 我不知道你要对Utils.delay做什么,但它不会起作用。

这些只是建议。如果不知道你想要做什么,我不知道他们是否会工作。

答案 1 :(得分:0)

所以你的CoffeeScript转换为JavaScript如下:

var cart, sandwich, supermarket;

supermarket = JSON.parse(Utils.domLoadScriptSync(URL));

cart = function(ingredients) {
  Utils.delay(5, function() {
    ingredients = supermarket[i].name;
    return ingredients;
  });
  return ingredients;
};

cart();

sandwich = new Layer({
  html: ingredients
});

听起来Utils.delay是一个异步函数,在运行前等待x秒。

所以当你调用cart()时它会启动一个计时器来运行Utils.delay中的函数,然后返回ingredients。但是函数Utils.delay尚未运行,因此ingredients不存在。

Utils.delay中的函数运行时,它获取值并返回它。 (不知道它返回的是什么。)

你到底想要做什么?这里的最终目标是什么?