공부

JS - Tag Function

프로필사진
fienestar
2022. 11. 2. 17:49

Mozilla Dev - tagged_templates
보고 신기해서 몇개 만들어봤다.

 

각 원소를 퍼센트로 나타내기

function persent(strings, ...values){
    let result = strings[0];
    let sum = values.reduce((a,b) => a+b);
    
    for(let i=0; i!=values.length; ++i)
        result += `${Math.floor(values[i]/sum*1000)/10}%` + strings[i+1];
    return result;
}

// a 50% b 33.3% c 16.6% d 0%
console.log(persent`a ${3} b ${2} c ${1} d ${0}`)

 

첫 인자로 오는 strings에 ${}로 split된 문자열들이 배열로 들어가고
뒷 인자로 ${}속에 있던 값들이 순서대로 들어간다.

 

tagged template의 기본 동작을 하는 tag function인 String.raw를 발견했는데, 이를 이용해 첫 소스코드를 개선하고, 약간 추가해봤다.

// 퍼센트로 나타내주기
function persent(strings, ...values){
    const sum = values.reduce((a,b) => a+b);
    
    return String.raw(
        strings,
        ...values.map(value => `${Math.floor(value/sum*1000)/10}%`)
    )
}

// a 50% b 33.3% c 16.6% d 0%
console.log(persent`a ${3} b ${2} c ${1} d ${0}`)

// 매 호출마다 개행해주기
function endl(strings, ...values){
    let result = ""
    function callback(strings, ...values){
        result += String.raw(strings, ...values) + "\n"
        return callback;
    }
    callback.toString = callback.valueOf = () => result;
    return callback(strings, ...values);
}

// Hello\nWorld\n!
console.log("" + endl
`Hello`
`World`
`!`
)

 

Q. 왜 values는 배열로 제공하지 않고 인자로 각각 넣었을까?