将变量作为参数传递给函数并为其赋值?

时间:2014-12-07 08:16:53

标签: javascript scope promise

在尝试学习如何使用JavaScript Promises时,我尝试实现一个允许将XHR的结果分配给变量的函数。我知道这可能不是解决这个问题的惯用方法。不过,如果我遇到令人费解的问题,这是一个有趣的问题。

我们的想法是将XHR包装在Promise中,并传递一个resolve函数,该函数将XHR响应分配给变量。以下是一些代码和解释。在控制台中测试它的一切都在这里:

function getJSON(url) {
  return new Promise(function(resolve, reject) {
  var xhr = new XMLHttpRequest();
  xhr.open("get", url);
  xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && xhr.status < 400) {
      resolve(xhr.responseText);
      }
     };
  xhr.send();
  });
}

function assignDataTo(target, url, ctx) {
  // Asynchronously assign JSON response to `target` variable
  getJSON(url)
    .then(function(data) {
         ctx.target = JSON.parse(data);
      }, function(error) {
         console.log(error);
      }
    );
}

var targetVariable,
    url = "https://data.baltimorecity.gov/resource/n4ma-fj3m.json?$select=*&$limit=5";

assignDataTo(targetVariable, url, window);
valueOf(targetVariable); // Error: undefined
valueOf(window.target); // JSON: xhr.response

将上下文参数添加到assignDataTo是为了更加具体地了解接收数据的变量的范围。我发现ctx.target(或ctx[target])评估为window.target,而不是像我希望的那样替换函数参数(即ctx.target == window.targetVariable)。

如何将指向实际变量的指针作为assignDataTo函数的参数传递给我? (其次,欢迎任何关于这种使用承诺的一般策略的评论。)

2 个答案:

答案 0 :(得分:2)

字符串,布尔值和数字在javascript中按值传递。但是,您可以将targetVariable包装在一个将通过引用传递的对象中。

ctx.target = JSON.parse(data);实际上只为target对象中的键ctx设置了一个值,在您的情况下它将是window对象。它与您作为参数传递给函数的参数target无关。

此外,assignDataTo()函数异步运行,因此调用valueOf(targetVariable)不起作用,因为Promise可能还没有解决,即。 XHR的结果尚未到来。更好的解决方案就是这样。

function assignDataTo(url) {
  // Return a Promise
  return getJSON(url)
    .then(function(data) {
       //resolve the Promise with this value
       return JSON.parse(data);
     }, function(error) {
       console.log(error);
     }
  );
}

var targetVariable;
//wait for the Promise to be resolved and then assign the variable and do whatever with it
assignDataTo(url).then(function(result) {
  targetVariable = result;
  valueOf(targetVariable);
});

答案 1 :(得分:0)

JavaScript没有像其他语言那样显式引用(或指针)(例如:PHP&amp; $ variable),但在使用对象时它使用引用。

当向函数发送数组(也是JavaScript中的对象)时,它将获得相同的数组引用。这就是为什么在函数内部进行任何更改的原因将在外面提供。

示例:

function addEl(arr) { 
  arr.push(3);
}

var ourArray = [1, 2]; // [1, 2]
addEl(ourArray);
console.log(ourArray); // [1, 2, 3]

这适用于Objects,但它与原始类型有所不同:string,number或boolean。 在向函数发送基元时,它会创建一个基元的副本,因此它不会从函数外部更改基元。

原语示例:

function increment(el) { 
  el += 1;
}

var numb = 1;
increment(numb);
console.log(numb); // 1

代码中的内容相同:

targetVariable

是一个原始变量

window

是一个对象。

写作时:

ctx.target

你实际上是在ctx中添加一个新参数(对窗口的引用)。如果您想更改&#39; targetVariable&#39;,请在您的函数中将JSON.parse(数据)分配给window.targetVariable:

function assignDataTo(url, ctx) {
  // Asynchronously assign JSON response to `target` variable
  getJSON(url)
    .then(function(data) {
       ctx.targetVariable = JSON.parse(data);
    }, function(error) {
      console.log(error);
    }
  );
}
// ...
assignDataTo(url, window);