在JavaScript中,有3种定义字符串的方式,分别是字符串字面量,直接调用String()函数与new String()构造函数。
var str = 'hello JavaScript'; // 正确写法
var str2 = "hello html"; // 正确写法
var str = 'hello css"; // 错误写法,首尾符号不一样
String(123); // '123'
String(123.12); // '123.12'
② 如果是Boolean类型的值,则直接转换成’true’或者’false’。
String(true); // 'true'
String(false); // 'false'
③ 如果值为null,则返回字符串’null’;
String(null); // 'null'
④ 如果值为undefined,则返回字符串’undefined’;
String(undefined); // 'undefined'
⑤ 如果值为字符串,则直接返回字符串本身;
String('this is a string'); // 'this is a string'
⑥ 如果值为引用类型,则会先调用toString()函数获取返回值,将返回值按照上述步骤①~⑤判断能否转换字符串类型,如果都不满足,则会调用对象的valueOf()函数获取返回值,并将返回值重新按照步骤①~⑤判断能否转换成字符串类型,如果也不满足,则会抛出类型转换的异常。
以下是通过toString()函数将对象正确转换成String类型的示例。
var obj = {
age: 21,
valueOf: function () {
return this.age;
},
toString: function () {
return 'good';
}
};
String(obj); // 'good'
以下是通过valueOf()函数将对象正确转换成String类型的示例。
var obj = {
age: '21',
valueOf: function () {
return this.age;
},
toString: function () {
return [];
}
};
String(obj); // '21'
如果toString()函数和valueOf()函数返回的都是对象类型而无法转换成原生类型时,则会抛出类型转换的异常。
var obj = {
age: '21',
valueOf: function () {
return [];
},
toString: function () {
return [];
}
};
String(obj); // 抛出异常TypeError: Cannot convert object to primitive value
new String('hello JavaScript'); // String {"hello JavaScript"}
基本字符串在作比较时,只需要比较字符串的值即可;而在比较字符串对象时,比较的是对象所在的地址。
我们看看以下用来测试相等的实例。
var str = 'hello';
var str2 = String(str);
var str3 = String('hello');
var str4 = new String(str);
var str5 = new String(str);
var str6 = new String('hello');
str === str2; // true
str2 === str3; // true
str3 === str4; // false
str4 === str5; // false
str5 === str6; // false
首先对于str、str2和str3,因为都是基本字符串,只需要比较字符串的值即可,三者字符串值都为’hello’,所以三者是互相严格相等的。
str === str2; // true
str2 === str3; // true
其次,对于str4、str5和str6,因为是使用new运算符生成的String类型的实例,所以在比较时需要判断变量是否指向同一个对象,即内存地址是否相同,很明显str4、str5、str6都是在内存中新生成的地址,彼此各不相同。
str4 !== str5; // true
str5 !== str6; // true
str4 !== str6; // true
同样,对于基本字符串和字符串对象的比较,在判断严格相等时,也会返回“false”。
str === str4; // false
str2 === str4; // false
'hello'.indexOf('e'); // 1
'hello'.substring(1); // 'ello'
'hello'.slice(1); // 'ello'
这是为什么呢?
实际上基本字符串本身是没有字符串对象的函数,而在基本字符串调用字符串对象才有的函数时,JavaScript会自动将基本字符串转换为字符串对象,形成一种包装类型,这样基本字符串就可以正常调用字符串对象的方法了。
基本字符串和字符串对象在经过eval()函数处理时,会产生不同的结果。
eval()函数会将基本字符串作为源代码处理,如果涉及表达式会直接进行运算,返回运算后的结果;而字符串对象则会被看作对象处理,返回对象本身。
var s1 = '2 + 2'; // 创建一个字符串字面量
var s2 = new String('2 + 2'); // 创建一个对象字符串
console.log(eval(s1)); // 4
console.log(eval(s2)); // String {"2 + 2"}
通过实例可以看出,在使用eval()函数处理字符串字面量时,进行了2 + 2 = 4的算术运算,并返回“4”;而使用eval()函数处理对象字符串时,会将’2 + 2’看成是一个对象,而不会进行运算,直接输出字符串本身。