字符串对象的使用频率恐怕比数组对象有过之而无不及,为什么我要放到后面来说呢,其实是因为对于字符串,我们要说的更多,而可扩展的方法和工具函数也更加丰富。我们一起先来看看 String 类本身吧。

创建一个字符串对象有以下几种方法:

方法一:var str = new String("Hello World");

方法二:var str = String("Hello World");

方法三:var str = "Hello World";

和数组对象一样,我推荐大家使用最后一种方法,及字符串字面量。关于是否有 new 的区别,周爱民老师的博客中有过很详细的解释,同时,如果你一直读下去,在介绍自定义对象的时候也会提到 new 运算符。

String 对象有且只有一个属性 length ,他返回字符串的长度,在这里我们必须要弄明白 JavaScript 是 unicode 编码,那么汉字和英文都当作一个字符长度来处理,之所以提到这个是因为曾经遇到不止一位朋友在论坛提问这个问题,呵呵,动手的必要性啊。那么如果我们非要把汉字当作 2 个字符长度来计算呢?这就带来了我们第一个自定义方法。

String.prototype.getLength = function(isSplit){

if(isSplit) {

return this.replace(/[^\u0000-\u00FF]/g,"tt").length;

else {

return this.length;

}

};

该方法通过传递一个 Boolean 类型的参数,如果为真则将非半角字符、数字、英文字母分割为 2 个长度来求长度,不用担心这个分割,他并不会修改字符串对象本身。如果为假,则直接返回 length 属性值。由于介绍方法不是根据方法的字符排列顺序而来,如果作为字典,我想还是 w3school 更合适,因为我是根据作用的不同和关联性来进行介绍。 ok ,介绍完了 length 属性,我们看看字符串查找吧。

indexOf 和 lastIndexOf 方法。

这两个方法从是从字符串中查找一个字符或字符子串,区别在于查找方向,前者是从位置 0 处开始查找,并返回第一个查找到的位置,后者从位置 length-1 处开始查找,并返回第一个查找到的位置。如果查找不到呢,返回 -1 。例如

var str = "了解面向对象编程和基于对象编程是一个基础理论";

alert(str.indexOf("对象")); //output:4

alert(str.lastIndexOf("对象"));//output:11

alert(str.indexOf("过程"));//output:-1

从输出的结果我可以得到以下结论:

1、 字符位置是从 0 开始索引

2、 即使是从后往前查找,返回位置时也还是位置 0 开始计算

3、 当在字符串中索引不到该子串时,返回 -1 值。

charAt 和 charCodeAt 方法根据一个位置索引来返回字符,其中前者是返回字符本身,后者返回字符编码。我们简单的看个例子后结束他们:

var str = "了解面向对象编程和基于对象编程是一个基础理论";

alert(str.charAt(5)); //output:象

alert(str.charCodeAt(5));//output:35937

接下来轮到 slice , substr 和 substring 方法,说实话很多熟悉 JavaScript 的程序员也经常会混淆两者的用法,并非是我夸张,而是 substring 和很多后台语言的 substring 方法区别很大的哦。先看看 slice 方法。

slice(start[,end]) 方法需要提供至少一个整数参数,作用是返回从 start 的位置开始到 end 位置的字符子串。接下来几句话请仔细看清楚了,以防造成曲解,当参数 start 为负数的时候他将从字符串尾部开始计算,当 end 没有指定时, end 即为字符串的结尾。如果为负数呢,他也要从字符串尾部开始计算。所以当我们需要一个字符串的之后 3 个字符时只需 slice(-3); 由此可见,合理的使用负数让我们的程序变得简单。但是在此之前,请确保自己了解了他的作用。

据我所知的编程语言中,有很大一部分的 substring 方法设计为 substring(beginposition,length) ,而在 JavaScript 中正好也有这么一个方法,可惜真正与之对应的是 substr 方法。 substr(pos[,length]) 方法中,如果 pos 为负数,则与 slice 的负数解释相同, length 省略时与 slice 的 end 省略也相同。

到了 substring 方法, substring(from[,to]); 从定义上就可以看到,后一个参数是一个位置,而非长度,因此他更像 slice ,但是与之有一点重要的区别,那就是 substring 方法不包含 to 位置。即是一个半开半闭区间。另一个区别是 substring 不支持负向位置,如果第一个参数为负数,那么就是从位置 0 开始。后一个位置如果是负数,则返回空串,如果第二个参数小于第一个参数,那么同样返回空串,但是如果相等呢,还是空串,因为这是一个半开半闭区间 [from,to) 。

另外几个查找的方法 :match 、 search 将在后面介绍正则表达式和 RegExp 类的时候详细介绍。替换方法 replace 也将在介绍正则表达式时介绍。另外一对有用的方法是 toLowerCase 和 toUpperCase 。他们就是将字符串进行大小写转换的。

字符串操作的另一个领悟的连接字符串。字符串对象是长度不可变的,仔细回顾下之前所有的方法中没有一个是修改对象本身的方法。关于这点将于稍后一个思考题单独会展开来介绍。现在你要做的就是知道这点。字符串对象的连接方法常见的三种,第一种是使用 concat 方法,在介绍 Array 类的时候我们也见过这个方法,他们其实是一样的东西,连接字符串为一个新串,另外字符串对象重载了 + 号运算符,用来简化连接操作,因此 "abc"+"de" == "abcde"; 还有一个方法是借助 Array 对象中的 push 和 join 方法连接字符串。

var arr = [];

for(var i = 0; i < 10; i++) {
arr.push("<img alt=\"test\" src=\"pic" + i + ".jpg\" />");

}

arr = arr.join("");

这种方法很类似与 C# 中的 StringBuilder 的 append 和 ToString 方法,而好处也很类似。不要忘了在 join 的方法中加上参数""哦,否则的话,多出的逗号可能就有点事与愿违了。为了方便操作,我们通常还会扩展一个方法来模拟 printf(in c) 和 format(in c#):
function formatString()  {

var args = arguments;

if(args.length > 1) {

return args[0].replace(new RegExp("\{([0-" + (args.length-2).toString() + "])\}","g"),function(s,m){

return args[+m+1];

});

}

}

首先我要说明,这个方法与原来的方法相比丑陋了许多,但是更容易理解,其次,这个方法有自身的 bug 存在,即当参数过多(>10)时,正则表达式将不能正确运转。因此我们换个解决方案来解决这个 bug (感谢zswang 的仔细,下面的解决方案也是仿照zswang的。)

function formatString(str,params) {

return str.replace(/\{(\d+)\}/g,function(s,m){

return params[+m];

});

}

alert(formatString("{0} is {1} old",['JeeChang',25]));

JavaScript 中没有一个 trim 方法,让我们很是苦恼,没有例外,我们自己写一个 trim 方法吧

String.prototype.trim = function(which){

var pattern = {

"left":"^\\s*",

"right":"\\s*$",

"both":"^\\s*|\\s*$"

}

return this.replace(new RegExp(pattern[which],'g'),"");

};

字符串的操作一直都不仅限于此,比如字符串截取往往还有这样的需求,即我们在浏览器显示的时候往往需要根据全半角来截断字符串,但是最后一个字符是全角的话则需要全部截断。看上去一定很复杂吧。没关系我们来添加这个方法。

String.prototype.splitCount = function(count){

var str = this;

var signs = ['~','!','|','`',':','$','#','&','*','@','.','?'];

var sign = '';

for(var i = 0; i < signs.length; i++) {

if(str.indexOf(signs[i]) < 0) {

sign = signs[i];

break;

}

}

str = str.replace(/[^\u0000-\u00FF]/g,sign + sign);

var ig = count;

for(var i = 0; i < count; i++) {

if(str[i] == sign)

ig-=0.5;

}

return this.substr(0,Math.floor(ig));

};

这个方法很可惜,替换字符不够全面,如果恰巧这些字符都存在于其中,那么结果就很可悲了。所以这个方法不是那么的可靠。其实可以通过初步判断总字符长度来截取掉后面的字符串然后再查找是否有替换字符。这样概率就相对小些。

介绍完了数组对象和字符串对象之后,我们看下面一个例子:

var a = "abc";

var b = "abc";

alert(a.valueOf() === b.valueOf);

alert(a.toString() === b.toString());

alert(a.valueOf() == b.valueOf());

var arr1 = ['a','b','c'];

var arr2 = ['a','b','c'];

alert(arr1.toString() === arr2.toString());

alert(arr1.valueOf() === arr2.valueOf());

请问输出结果是什么呢?


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cj205/archive/2011/01/23/6159709.aspx

JavaScript 最后修改于 2011-02-09 11:36:32
上一篇