最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Passing string as parameter by reference - Stack Overflow

programmeradmin0浏览0评论

I want to alter the contents of a string in a function, for example

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

I'd like to have s altered on return but as string is a primitive is being passed by value so the modifications do not affect the original.

What is the most efficient/clean way to deal with this? (I try to keep code concise)

I want to alter the contents of a string in a function, for example

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

I'd like to have s altered on return but as string is a primitive is being passed by value so the modifications do not affect the original.

What is the most efficient/clean way to deal with this? (I try to keep code concise)

Share Improve this question edited Mar 5, 2018 at 17:37 Huangism 16.4k7 gold badges50 silver badges75 bronze badges asked Mar 5, 2018 at 17:31 tru7tru7 7,2426 gold badges42 silver badges71 bronze badges 3
  • 4 You can have the function return the new string. JavaScript is always pass-by-value. – Pointy Commented Mar 5, 2018 at 17:33
  • 1 Make a method and return the new value? There is no real magical solution. – epascarello Commented Mar 5, 2018 at 17:33
  • 1 You can always set the original string's content to the returned string of your function, once you return the new string – Huangism Commented Mar 5, 2018 at 17:36
Add a ment  | 

4 Answers 4

Reset to default 7

JavaScript has no out parameters if that's what you mean. The simplest way of dealing with this is to pass the string in an object.

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

Global Variables

While string primitives are not passed by reference, one option not mentioned is the ability to use global variables. Of my own conscience, I must advise against this, but not knowing your use case you should know of your options:

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 Assignment

Of course you could build your own function and use the return variable as an assignment. Below I've used a prototype function, but should also advise against this, without fully understanding the implications (experience can take years) — you may see that I'm teaching you what not to do:

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)

Here's a "better" way to do the same. Although efficient, the untrained eye might struggle to understand what is occurring in the body of the function. It's subjective, but for maintainability you might want to make something more readable:

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 || '|')
};


Object Mutation / Scoping

The final thing you can do is modify an object. Not only will this get close to what it seems you'd like, but in larger applications is very nice to scope variables in objects to avoid collision and ease debugging (though, at the cost of a performance penalty):

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 || '|')
};

A similar question was made here, and the answers include implementation alternatives.

Long story short: wrap the string you would like to "pass by reference" in an object, then modify the object, as shown in 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);

You could return the new string.

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', ', '));

With an object, you could take the object, the separated key and the other parts and update this property.

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

appendSeparating(clients[index].address, 'postalCode', 'foo', ', ');
发布评论

评论列表(0)

  1. 暂无评论