任何人都可以解释这个关于字符串连接的奇怪的JS行为吗?

时间:2012-03-28 18:04:40

标签: javascript string scope

我刚刚发布了这个要点:https://gist.github.com/2228570

var out = '';

function doWhat(){
    out += '<li>';
    console.log(out === '<li>'); // at this point, out will equal '<li>'
    return '';
}

out += doWhat();
console.log(out, out === '<li>');
// I expect out to == '<li>', but it's actually an empty string!?

这种行为很奇怪,有没有人有解释?谷歌这是一件很难的事情。如果您使用out +=out = out +

,也没有任何区别

编辑:@paislee制作了一个JSFiddle,它演示了如何在一个单独的行上做什么,它的行为符合预期:http://jsfiddle.net/paislee/Y4WE8/

4 个答案:

答案 0 :(得分:7)

您似乎期望在评估doWhat之前调用+=

但是,该行的进展是:

out += doWhat();      // original line
out = out + doWhat(); // expand `+=`
out = '' + doWhat();  // evaluate `out`, which is currently an empty string
out = '' + '';        // call `doWhat`, which returns another empty string
out = '';             // result

out += '<li>';内的doWhat正在更新变量,但为时已晚,无法产生持久影响。

答案 1 :(得分:6)

令人困惑的是,您希望doWhat()也可以直接修改out。显然,在调用此函数之前,将检索要附加的值。

这是逻辑:

  1. 获取out('')
  2. 的值
  3. 致电doWhat()并将结果追加到第一个值(''+''='')
  4. 将结果分配给out('')
  5. 以这种方式混合返回值和直接修改只是要求解决问题,正如您的示例中所说明的那样。也许您应该尝试返回<li>

答案 2 :(得分:2)

想象一下:

// out is undefined
var out = '';
// out is ''
function doWhat(){
 out += '<li>';
 // out is '<li>';
 return '';
}
out = out + doWhat();
// out += doWhat(); is the same as:
// out = out + doWhat(); is the same as :
// out = '' + doWhat; because the value of `out` is read when `out` is first found
// out is ''

线性化:

// out is undefined
var out = '';
// out is ''
out += '<li>';
// out is '<li>';
out = '' + ''; // first '' is value of `out` before function is called, second is what the function returns
// out is ''

解决方案

var out = '';
function doWhat(){
 out += '<li>';
 return '';
}
out = doWhat() + out; // Note `out` is *after* `doWhat()`

TL; DR

目前,您的代码的评估方式与:

相同
out = out + doWhat();

在调用 out之前,它会读取doWhat() 的值。为了使它按预期工作,只需颠倒顺序:

out = doWhat() + out;

这将按照您的预期读取 out之后doWhat() 的值。

答案 3 :(得分:1)

正如Jonathan上面所说,你从函数返回一个空字符串,所以即使你通过在'<li>'里面out附加doWhat来修改全局变量,在进行函数调用时,javascript将把函数的返回值附加到out的值。

您也可以这样做:

var out = '';

function doWhat(){
    out += '<li>';
    return true;
}

doWhat();

是否有任何特殊原因需要在函数内部和返回值之后向字符串添加内容?

[编辑]

查看您在此答案的评论中发布的实际示例,在我看来,您可能会尝试有条件地返回一个附加值以从out附加到doWhat。如我错了请纠正我。您的代码如下所示:

var out = '', temp;

function doWhat(){
   out += '<li>';
}

out += typeof (temp = doWhat()) === 'undefined' ? '' : temp;

从这个演示文稿中,temp的值将始终未定义,因为该函数不返回任何可以键入的内容。如果你计划让函数有时返回一个你追加的值,你可以通过在最后将它分成两行来实现你想要的:

var out = '', temp;
function doWhat(){
    out += '<li>';
}
temp = doWhat();
out += typeof (temp === undefined) ? '' : temp;

虽然这有点尴尬,但我可能会尝试将两个追加移动到函数内部。

var out = '';
function doWhat () {
   out += '<li>';
   if (some condition is met) { out += 'some extra string'; }
}
doWhat();