How can I do string interpolation in JavaScript?

前端 未结 19 2533
慢半拍i
慢半拍i 2020-11-21 07:54

Consider this code:

var age = 3;

console.log(\"I\'m \" + age + \" years old!\");

Are there any other ways to insert the value of a variabl

相关标签:
19条回答
  • 2020-11-21 08:14

    Expanding on Greg Kindel's second answer, you can write a function to eliminate some of the boilerplate:

    var fmt = {
        join: function() {
            return Array.prototype.slice.call(arguments).join(' ');
        },
        log: function() {
            console.log(this.join(...arguments));
        }
    }
    

    Usage:

    var age = 7;
    var years = 5;
    var sentence = fmt.join('I am now', age, 'years old!');
    fmt.log('In', years, 'years I will be', age + years, 'years old!');
    
    0 讨论(0)
  • 2020-11-21 08:14

    Custom flexible interpolation:

    var sourceElm = document.querySelector('input')
    
    // interpolation callback
    const onInterpolate = s => `<mark>${s}</mark>`
    
    // listen to "input" event
    sourceElm.addEventListener('input', parseInput) 
    
    // parse on window load
    parseInput() 
    
    // input element parser
    function parseInput(){
      var html = interpolate(sourceElm.value, undefined, onInterpolate)
      sourceElm.nextElementSibling.innerHTML = html;
    }
    
    // the actual interpolation 
    function interpolate(str, interpolator = ["{{", "}}"], cb){
      // split by "start" pattern
      return str.split(interpolator[0]).map((s1, i) => {
        // first item can be safely ignored
    	  if( i == 0 ) return s1;
        // for each splited part, split again by "end" pattern 
        const s2 = s1.split(interpolator[1]);
    
        // is there's no "closing" match to this part, rebuild it
        if( s1 == s2[0]) return interpolator[0] + s2[0]
        // if this split's result as multiple items' array, it means the first item is between the patterns
        if( s2.length > 1 ){
            s2[0] = s2[0] 
              ? cb(s2[0]) // replace the array item with whatever
              : interpolator.join('') // nothing was between the interpolation pattern
        }
    
        return s2.join('') // merge splited array (part2)
      }).join('') // merge everything 
    }
    input{ 
      padding:5px; 
      width: 100%; 
      box-sizing: border-box;
      margin-bottom: 20px;
    }
    
    *{
      font: 14px Arial;
      padding:5px;
    }
    <input value="Everything between {{}} is {{processed}}" />
    <div></div>

    0 讨论(0)
  • 2020-11-21 08:14

    While templates are probably best for the case you describe, if you have or want your data and/or arguments in iterable/array form, you can use String.raw.

    String.raw({
      raw: ["I'm ", " years old!"]
    }, 3);
    

    With the data as an array, one can use the spread operator:

    const args = [3, 'yesterday'];
    String.raw({
      raw: ["I'm ", " years old as of ", ""]
    }, ...args);
    
    0 讨论(0)
  • 2020-11-21 08:16

    I can show you with an example:

    function fullName(first, last) {
      let fullName = first + " " + last;
      return fullName;
    }
    
    function fullNameStringInterpolation(first, last) {
      let fullName = `${first} ${last}`;
      return fullName;
    }
    
    console.log('Old School: ' + fullName('Carlos', 'Gutierrez'));
    
    console.log('New School: ' + fullNameStringInterpolation('Carlos', 'Gutierrez'));

    0 讨论(0)
  • 2020-11-21 08:17

    Since ES6, you can use template literals:

    const age = 3
    console.log(`I'm ${age} years old!`)

    P.S. Note the use of backticks: ``.

    0 讨论(0)
  • 2020-11-21 08:17

    tl;dr

    Use ECMAScript 2015's Template String Literals, if applicable.

    Explanation

    There is no direct way to do it, as per ECMAScript 5 specifications, but ECMAScript 6 has template strings, which were also known as quasi-literals during the drafting of the spec. Use them like this:

    > var n = 42;
    undefined
    > `foo${n}bar`
    'foo42bar'
    

    You can use any valid JavaScript expression inside the {}. For example:

    > `foo${{name: 'Google'}.name}bar`
    'fooGooglebar'
    > `foo${1 + 3}bar`
    'foo4bar'
    

    The other important thing is, you don't have to worry about multi-line strings anymore. You can write them simply as

    > `foo
    ...     bar`
    'foo\n    bar'
    

    Note: I used io.js v2.4.0 to evaluate all the template strings shown above. You can also use the latest Chrome to test the above shown examples.

    Note: ES6 Specifications are now finalized, but have yet to be implemented by all major browsers.
    According to the Mozilla Developer Network pages, this will be implemented for basic support starting in the following versions: Firefox 34, Chrome 41, Internet Explorer 12. If you're an Opera, Safari, or Internet Explorer user and are curious about this now, this test bed can be used to play around until everyone gets support for this.

    0 讨论(0)
提交回复
热议问题