The template string may be a new feature of ES6 that we are familiar with. It allows us to insert variables in the string, and can also wrap lines, etc. It is indeed very convenient to use. However, ES6 also added a new label function mainly used in conjunction with template strings.
1. What label function?
As the name suggests, the label function is also a function. This is a very simple label function declaration:
function tagFoo() {
console.log('这是一个标签函数');
}
Take a closer look and see tagFoo
and our commonly used ordinary functions? Is there no difference? This conclusion is normal, because the label is actually a function of a function, so its declarations and function declarations are exactly the same of.
So, how do we know that tagFoo
is a label function, or what is special about the label function compared to ordinary functions? The answer is to look at tagFoo
of invocation .
tagFoo();//这是一个标签函数
tagFoo`一个模板字符串`;//这是一个标签函数
In addition to being a normal function, the label function can be ()
, and it can also be called using the template string `` . In other words, When a function is called using a template string, this function can be called a label function , so we might as well understand the label function as a new function call method.
Then we might think, what is the difference between these two calling methods? What are their return values?
Regardless of the calling method, this function is called, and the final return value is also the result of executing this function. Let tagFoo
add a return value to 061a5c4f66daa2 to see:
function tagFoo() {
return '我是返回值';
}
let res1 = tagFoo();
let res2 = tagFoo`一个模板字符串`;
console.log({ res1, res2 });//{ res1: '我是返回值', res2: '我是返回值' }
2. The parameters of the label function
excuse me? Do these two calling methods only look different? of course not. Thinking about it, we have all noticed that the normal function call method allows us to pass in parameters by ourselves, while the label function call method does not seem to provide us with the opportunity to pass in parameters. Let's take a look at the label function when there are parameters, what are its parameters:
function tagFoo(...args) {
console.log(...args);
}
tagFoo`一个普通的模板字符串`; // [ '一个普通的模板字符串' ]
tagFoo`一个有插值的模板字符串:${'var'}`; //[ '一个有插值的模板字符串:', '' ] var
tagFoo`一个有插值的模板字符串:${'var1'}-${'var2'}`; //[ '一个有插值的模板字符串:', '-', '' ] var1 var2
As can be seen from the above, when the label function is called, one parameter received is always an array, and the elements in the array are the string part of the template string; the remaining parameters starting from the second parameter receive the template string The number of interpolation variables is arbitrary. It may be more intuitive to declare in another way:
function tagFoo(templateStrings, ...insertVars) {
console.log({ templateStrings, insertVars });
}
tagFoo`一个普通的模板字符串`; //{ templateStrings: [ '一个普通的模板字符串' ], insertVars: [] }
tagFoo`一个有插值的模板字符串:${'var'}`; //{ templateStrings: [ '一个有插值的模板字符串:', '' ], insertVars: [ 'var' ] }
tagFoo`一个有插值的模板字符串:${'var1'},${'var2'}`; //{ templateStrings: [ '一个有插值的模板字符串:', '-', '' ], insertVars: [ 'var1', 'var2' ] }
It can also be represented by a picture:
Might be described as, templateStrings
between each of the two elements should have a insertVars
variable inserted. The order of the elements in the two arrays is corresponding.
3. What is the use of the label function?
The label function allows us to perform our own logical behavior based on the template string, making some operations very simple.
For a simple example, convert the price n
in the template string to $n
:
function $(templateStrings, ...insertVars) {
return templateStrings.reduce((res, temp, i) => {
return res + temp + (i >= insertVars.length ? '' : '$' + insertVars[i]);
}, '');
}
console.log($`1号衣服原价${42},打折后的价格是${2}`); //1号衣服原价$42,打折后的价格是$2
console.log($`2号鞋子原价${58},打折后的价格是${88}`); //2号鞋子原价$58,打折后的价格是$88
This effect can of course be achieved without using the label function, and it is also very simple:
function $(n) {
return '$' + n;
}
console.log(`1号衣服原价${$(42)},打折后的价格是${$(2)}`); //1号衣服原价$42,打折后的价格是$2
console.log(`2号鞋子原价${$(58)},打折后的价格是${$(88)}`); //2号鞋子原价$58,打折后的价格是$88
Which method to use depends on our own preferences.
However, when dealing with some special situations, the label function may give us a big surprise.
For example, styled-components did:
const Button = styled.a`
/* This renders the buttons above... Edit me! */
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
/* The GitHub button is a primary button
* edit this to target it specifically! */
${props => props.primary && css`
background: white;
color: black;
`}
`
The Button
obtained is a React
component. Through styled-components , we can write css styles in JS!
We can also imitate styled-components to achieve a simple styled.a
const styled = {
a(stringProps, ...getProps) {
const varProps = getProps.map((f) => f({}) || '');
const style = stringProps
.reduce((prop, stringProp, i) => {
return (
prop +
stringProp +
(i >= varProps.length ? '' : varProps[i])
);
}, '')
//删除注释和换行
.replace(/(\n|(\/\*[\s\S]*?\*\/))/g, '')
//删除空格
.replace(
/\s*?(?<propName>\w+):(?<propValue>[\s\S]*?);\s*/g,
(...args) => {
const { propName, propValue } = args.pop();
return `${propName}:${propValue};`;
}
);
//为了方便展示,返回一个字符串
return `<a style="${style}"></a>`;
},
};
const Button = styled.a`
/* This renders the buttons above... Edit me! */
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
/* The GitHub button is a primary button
* edit this to target it specifically! */
${(props) => !props.primary && 'background: white;'}
`;
console.log(Button);
//<a style="display: inline-block;border-radius: 3px;padding: 0.5rem 0;margin: 0.5rem 1rem;width: 11rem;background: transparent;color: white;border: 2px solid white;background: white;"></a>
I have to say that the label function is really attractive when dealing with strings.
Of course, whether you will use the label function or not depends on your own preferences. Each has its own preference.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。