JavaScript 原始类型类型二(String)

162 阅读2分钟

String(字符串)数据类型表示零或多个16位Unicode字符序列。字符串可以使用双引号("),单引号(')或反引号(`)表示。

    let firstName = "John";
    let lastName = 'Jacob';
    let lastHamr = `wangyi`;

ECMAScript中的字符串是不可变的,意思是一旦创建,他们的值就不变了。要修改某个变量的字符串的值,必须先销毁原始的字符串,然后将包含新值的另一个字符串的值保存到该变量。

    let lang = "Java";
    lang = lang + Script;

转换为字符串

有两种方式把一个值转换为字符串。首先是几乎所有值都有的toString()方法。这个方法唯一的用途就是返回当前值的字符串的等价物。

toString()

toString()方法可用于数值,布尔值,对象和字符串值。null和undefined值没有toString()方法。
多数情况下,toString()不接收任何参数。不过在对数值调用这个方法时,toString()可以接收一个底数参数,即以什么底数来输出数值的字符串表示。默认情况下,toString()返回数值的十进制表示。

    let num = 10;
    console.log(num.toString());//"10"
    console.log(num.toString(2));//"1010"
    console.log(num.toString(8));//"12"
    console.log(num.toString(10));//"10"
    console.log(num.toString(16));//"a"

String()转型函数

String()函数遵循如下规则:
如果值有toString()方法,则用该方法(不传参数)并返回结果。
如果值是null,返回“null”。
如果值是undefined,返回”undefined“。

模版字面量

ECMAScript 6 新增了 使用模版字面量定义字符串的能力。与使用单引号或双引号不同。模版字面量保留换行符,可以跨行定义字符串。

    let testString = 'first line\nsecond line';
    let templateString = `first line
    second line`;
    console.log(testString);
    //first line
    //second line
    console.log(templateString);
    //first line
    //second line

模版字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。技术上讲,模版字面量不是字符串,而是一种特殊的JavaScript 句法表达式,只不过求值得到的是字符串。模版字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。

字符串插值通过${}中使用一个JavaScript 表达式实现。

let value = 5let exponent = 'second';
let interpolatedTemplate = `${value} to the ${exponent} power is ${value * value}`;
console.log(interpolatedTemplate);//5 to the second power is 25

所有插入的值都会使用toString()强制转型为字符串,而且任何JavaScript表达式都可以用于插值。
将表达式转换为字符串时,会调用toString():

let foo = {toString() => 'World'};
console.log(`Hello,${foo}!`); // Hello, World!

在插值表达式中可以调用函数和方法。

function capitalize(word) {
return `${word[0].toUpperCase()}${word.slice(1)}`;
}

console.log(`${ capitalize('hello')},${capitalize('world')}!`);// Hello,World! 

模版字面量标签函数

模版字面量也支持 定义标签函数,而通过标签函数可以自定义插值行为。
标签函数会接收被插值记号分割后的模版和对每个表达式求值的结果。
标签函数本身是一个常规函数,通过前缀到模版字面量来应用自定义行为。
标签函数接受的参数依次是,去除掉插值符号后被拆分的原始字符串的字符数组,和对每个表达式求值的结果。
这个函数的返回值是对模版字面量求值的到的字符串。

    let a = 6,
    b = 9;
    //模版字面量标签函数,同普通函数一样
    function simpleTag(strings,aValExpression,bValExpression,sumExpression){
        console.log(strings);//被拆分后的原始字符串的字符串数组 [""," + "," = ",""]
        console.log(aValExpression);//6
        console.log(bValExpression);//9
        console.log(sumExpression);//15

        return 'foobar';
    }


    let untaggedResult = `${a} + ${b} = ${a + b}`;
    let taggedResult = simpleTag`${a} + ${b} = ${a + b}`;//模版字面量标签函数的调用。
    console.log(untaggedResult);//"6 + 9= 15"
    console.log(taggedResult);//"foobar"

对于有n个插值的模版字面量,传给标签函数的表达式参数的个数始终是n,而传给标签函数的第一个参数所包含的字符串的个数则始终是n+1。因此,如果你想把这些字符串和对表达式求值的结果拼接起来作为默认返回的字符串,可以这么做:

    let a = 6,
    b = 9;
 
    function zipTag(strings,...expressions){
      return strings[0] + expressions.map((e,i)=>`${e}${strings[i+1]}`).join('');
    }


    let untaggedResult = `${a} + ${b} = ${a + b}`;//"6 + 9= 15"
    let taggedResult = zipTag`${a} + ${b} = ${a + b}`;//模版字面量标签函数的调用。
    console.log(untaggedResult);//"6 + 9= 15"
    console.log(taggedResult);//"6 + 9= 15"

原始字符串

使用模版字面量也可以直接获取原始的模版字面量内容(如换行符或Unicode字符),而不是被转换后的字符表示。为此,可以使用默认的String.raw标签函数。

    console.log('first line\nseconde line');
    //first line
    //second line
    console.log(String.raw`first line\nsecond line`);//"first line\nsecond line"

另外,也可以通过标签函数的第一个参数,即字符串数组的.raw属性取得每个字符串的原始内容:

function printRaw(strings){
    console.log('Actual strings');
    for(const string of strings) {
        console.log(string);
    }
    
    console.log('Escaped characters:');
    for(const rawString of strings.raw){
        console.log(rawString);
    }
}
printRaw`\u00A9${'and'}\n`;
//Actual strings
//©
//换行符
//Escaped characters:
//\u00A9
//\n