通过引用将字符串作为参数传递

时间:2018-03-05 17:31:28

标签: javascript string pass-by-reference

我想改变函数中字符串的内容,例如

function appendSeparating(s, s2, separator) {
    if (s != "")
        s += separator;
    s += s2;
}

我希望在返回时更改,但因为字符串是基元,所以修改不会影响原始值。

处理此问题的最有效/最干净的方法是什么? (我尽量保持代码简洁)

4 个答案:

答案 0 :(得分:7)

JavaScript没有out参数,如果这就是你的意思。处理此问题的最简单方法是将字符串传递给对象。

function appendSeparating(stringObj, s2, separator) {
    if (stringObj.text != "")
        stringObj.text += separator;
    stringObj.text += s2;
}

答案 1 :(得分:1)

您可以返回新字符串。



function appendSeparating(s, s2, separator) {
    s += s && separator;
    return s + s2;
}

var x = '';

console.log(x = appendSeparating(x, 'one', ', '));
console.log(x = appendSeparating(x, 'two', ', '));
console.log(x = appendSeparating(x, 'three', ', '));




使用对象,您可以获取对象,分隔的键和其他部分,并更新此属性。

function appendSeparating(object, key, s2, separator) {
    object[key] += object[key] && separator;
    return object[key] += s2;
}

appendSeparating(clients[index].address, 'postalCode', 'foo', ', ');

答案 2 :(得分:1)

提出了类似的问题here,答案包括实施备选方案。

长话短说:在对象中包装你想要“通过引用传递”的字符串,然后修改对象,如this fiddle

所示
function concatStrings(stringObj, s2, separator) {
    stringObj.value = stringObj.value + separator + s2;
}

var baseString = "hello";
var stringObj = {value: baseString};
var s2 = "world";
var separator = " ";

concatStrings(stringObj, s2, separator);

window.alert(stringObj.value);

答案 3 :(得分:1)

全局变量

虽然字符串基元不是通过引用传递的,但未提及的一个选项是使用全局变量的能力。我自己的良心,我必须反对这一点,但不知道你的用例,你应该知道你的选择:

s = 'a'                       // created as a global variable
appendSeparating('b', '|')    // function now takes only two arguments
console.log(s)                // global variable affected

function appendSeparating(s2, separator) {
  // s is a global variable
  if (typeof s === 'undefined')
    return;

  if (s != "")
    s += separator;
  s += s2;
}

退货分配

当然,您可以构建自己的函数并使用return变量作为赋值。下面我使用了原型函数,但是也应该反对这一点,而不完全理解其含义(经验可能需要数年) - 你可能会看到我教你不该做的事情:

String.prototype.append = function(str, delimiter) {
  return [this, str].filter(v => v !== '').join(delimiter || '|')
};


let ex1 = 'a'
ex1 = ex1.append('b')
console.log('no delim: ', ex1)


let ex2 = 'a'
ex2 = ex2.append('b', '-')
console.log('w/ delim: ', ex2)

这是一种“更好”的方式来做同样的事情。虽然有效,但未经训练的眼睛可能很难理解功能体内发生的事情。这是主观的,但为了可维护性,您可能希望使其更具可读性:

let ex1 = 'a'
ex1 = append(ex1, 'b')
console.log('no delim: ', ex1)


let ex2 = 'a'
ex2 = append(ex2, 'b', '-')
console.log('w/ delim: ', ex2)


function append(prefix, suffix, delimiter) {
  return [prefix, suffix].filter(v => v !== '').join(delimiter || '|')
};

对象突变/范围

你可以做的最后一件事是修改一个对象。这不仅会接近您所希望的样子,而且在较大的应用程序中非常适合将对象范围放在对象中以避免冲突并简化调试(但是,以性能损失为代价):

const strings = {}

// Assuming key name
strings.s = 'foo'
append(strings, 'bar', ': ')
console.log(strings.s)

// Supplying key name
strings.x = 'x'
appendNamed(strings, 'x', 'y')
console.log(strings.x)



function append(str, suffix, delimiter) {
  str.s = [str.s, suffix].filter(v => v !== '').join(delimiter || '|')
};

function appendNamed(str, strName, suffix, delimiter){
  str[strName] = [str[strName], suffix].filter(v => v !== '').join(delimiter || '|')
};

相关问题