当前位置:  首页>> 技术小册>> Javascript重点难点实例精讲(一)

在JavaScript中,有3种定义字符串的方式,分别是字符串字面量,直接调用String()函数与new String()构造函数。

  1. 字符串字面量
    字符串字面量就是直接通过单引号或者双引号定义字符串的方式。
    需要注意的是,在JavaScript中,单引号和双引号是等价的,都可以用来定义字符串,只不过使用单引号开头的字符串就要使用单引号结尾,使用双引号开头的字符串就要使用双引号结尾。
  1. var str = 'hello JavaScript'; // 正确写法
  2. var str2 = "hello html"; // 正确写法
  3. var str = 'hello css"; // 错误写法,首尾符号不一样
  1. 直接调用String()函数
    直接调用String()函数,会将传入的任何类型的值转换成字符串类型,在转换时遵循的规则如下。
    ① 如果是Number类型的值,则直接转换成对应的字符串。
  1. String(123); // '123'
  2. String(123.12); // '123.12'

② 如果是Boolean类型的值,则直接转换成’true’或者’false’。

  1. String(true); // 'true'
  2. String(false); // 'false'

③ 如果值为null,则返回字符串’null’;

  1. String(null); // 'null'

④ 如果值为undefined,则返回字符串’undefined’;

  1. String(undened); // 'undefined'

⑤ 如果值为字符串,则直接返回字符串本身;

  1. String('this is a string'); // 'this is a string'

⑥ 如果值为引用类型,则会先调用toString()函数获取返回值,将返回值按照上述步骤①~⑤判断能否转换字符串类型,如果都不满足,则会调用对象的valueOf()函数获取返回值,并将返回值重新按照步骤①~⑤判断能否转换成字符串类型,如果也不满足,则会抛出类型转换的异常。

以下是通过toString()函数将对象正确转换成String类型的示例。

  1. var obj = {
  2. age: 21,
  3. valueOf: function () {
  4. return this.age;
  5. },
  6. toString: function () {
  7. return 'good';
  8. }
  9. };
  10. String(obj); // 'good'

以下是通过valueOf()函数将对象正确转换成String类型的示例。

  1. var obj = {
  2. age: '21',
  3. valueOf: function () {
  4. return this.age;
  5. },
  6. toString: function () {
  7. return [];
  8. }
  9. };
  10. String(obj); // '21'

如果toString()函数和valueOf()函数返回的都是对象类型而无法转换成原生类型时,则会抛出类型转换的异常。

  1. var obj = {
  2. age: '21',
  3. valueOf: function () {
  4. return [];
  5. },
  6. toString: function () {
  7. return [];
  8. }
  9. };
  10. String(obj); // 抛出异常TypeError: Cannot convert object to primitive value
  1. new String()构造函数
    new String()构造函数使用new运算符生成String类型的实例,对于传入的参数同样采用和上述String()函数一样的类型转换策略,最后的返回值是一个String类型对象的实例。
  1. new String('hello JavaScript'); // String {"hello JavaScript"}
  1. 三者在作比较时的区别
    使用第一种字符串字面量方式和第二种直接调用String()函数的方式得到的字符串都是基本字符串,而通过第三种方式,new运算符生成的字符串是字符串对象。

基本字符串在作比较时,只需要比较字符串的值即可;而在比较字符串对象时,比较的是对象所在的地址。
我们看看以下用来测试相等的实例。

  1. var str = 'hello';
  2. var str2 = String(str);
  3. var str3 = String('hello');
  4. var str4 = new String(str);
  5. var str5 = new String(str);
  6. var str6 = new String('hello');
  7. str === str2; // true
  8. str2 === str3; // true
  9. str3 === str4; // false
  10. str4 === str5; // false
  11. str5 === str6; // false

首先对于str、str2和str3,因为都是基本字符串,只需要比较字符串的值即可,三者字符串值都为’hello’,所以三者是互相严格相等的。

  1. str === str2; // true
  2. str2 === str3; // true

其次,对于str4、str5和str6,因为是使用new运算符生成的String类型的实例,所以在比较时需要判断变量是否指向同一个对象,即内存地址是否相同,很明显str4、str5、str6都是在内存中新生成的地址,彼此各不相同。

  1. str4 !== str5; // true
  2. str5 !== str6; // true
  3. str4 !== str6; // true

同样,对于基本字符串和字符串对象的比较,在判断严格相等时,也会返回“false”。

  1. str === str4; // false
  2. str2 === str4; // false
  1. 函数的调用
    在String对象的原型链上有一系列的函数,例如indexOf()函数、substring()函数、slice()函数等,通过String对象的实例可以调用这些函数做字符串的处理。
    但是我们发现,采用字面量方式定义的字符串没有通过new运算符生成String对象的实例也能够直接调用原型链上的函数。
  1. 'hello'.indexOf('e'); // 1
  2. 'hello'.substring(1); // 'ello'
  3. 'hello'.slice(1); // 'ello'

这是为什么呢?
实际上基本字符串本身是没有字符串对象的函数,而在基本字符串调用字符串对象才有的函数时,JavaScript会自动将基本字符串转换为字符串对象,形成一种包装类型,这样基本字符串就可以正常调用字符串对象的方法了。
基本字符串和字符串对象在经过eval()函数处理时,会产生不同的结果。
eval()函数会将基本字符串作为源代码处理,如果涉及表达式会直接进行运算,返回运算后的结果;而字符串对象则会被看作对象处理,返回对象本身。

  1. var s1 = '2 + 2'; // 创建一个字符串字面量
  2. var s2 = new String('2 + 2'); // 创建一个对象字符串
  3. console.log(eval(s1)); // 4
  4. console.log(eval(s2)); // String {"2 + 2"}

通过实例可以看出,在使用eval()函数处理字符串字面量时,进行了2 + 2 = 4的算术运算,并返回“4”;而使用eval()函数处理对象字符串时,会将’2 + 2’看成是一个对象,而不会进行运算,直接输出字符串本身。


该分类下的相关小册推荐: