JavaScript 基本包装类型

为了便于操作基本类型值, ECMAScript 提供了 3 个特殊的引用类型: Boolean、Number和String。这些类型具有基本类型相应的特殊行为。

每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据 。

var s1 = "some text";
var s2 = s1.substring(2);

为了让我们事先这种直观的操作,后台已经自动完成了一系列的处理。当第二个行代码访问 s1 时,访问过程处于一种读取模式,也就是要从内存中读取这个字符串。而在读取模式中访问字符串时,后台都会自动完成下列处理:

  1. 创建 String 类型的一个实例。
  2. 在实例上调用指定的方法;
  3. 销毁这个实例。

将以上三步想象为 ECMAScript 执行了:

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

Boolean

Boolean 类型是与布尔值对应的引用类型。要创建 Boolean 对象,可以像下面这样调用 Boolean 构造函数并传入 true 或 false 值。

var booleanObject = new Boolean(true);

建议永远不要使用 Boolean 对象

Number

Number 是与数字值对应的引用类型。要创建 Number 对象,可以在调用 Number 构造函数时向其传递相应的数值。

var numberObject = new Number(0);

可以以 toString() 方法传递一个表示基数的参数,告诉它返回几进制数值和字符串形式。

var num = 10;
alert(num.toString()); // 10
alert(num.toString(2)); // 1010
alert(num.toString(8)); // 12
alert(num.toString(10)); // 10
alert(num.toString(16)); // a

Number 参数格式化方法

toFixed()

toFixed() 方法会按照指定的小数位返回数值的字符串表示:

var num = 10;
alert(num.toFixed(2)); // 10.00

var num = 10.005;
alert(num.toFixed(2)); // 10.01

给 toFixed() 方法传入数值2,意思是显示几位小数。

如果数值本身包含小数位比指定的还要多,那么接近指定最大小数位的值就会舍入。

toFixed() 很适合处理货币值。

toFixed() 方法可以表示带有 0 到 20 个小数位的数值。但这只是标准实现的范围,有些浏览器也可能支持更多位数。

toExponential()

toExponential() 方法返回以指数表示法(也称e表示法)表示的数值的字符串形式。

var num = 10;
alert(num.toExponential(1)); // 1..0e+1

toPrecision()

toPrecision() 方法可能会返回固定大小(fixed)格式,也可能返回指数(exponential)格式;具体规则是看哪种格式最合适。

var num = 99;
alert(num.toPrecision(1)); // 1e+2
alert(num.toPrecision(2)); // 99
alert(num.toPrecision(3)); // 99.0

String

String 类型是字符串的对象包装类型。

var stringObject = new String("hello world");

String 类型的每个实例都有一个 length 属性,表示字符串中包含多个字符。

var stringValue = "hello world";
alert(stringValue.length); // 11

字符方法 charAt()、charCodeAt()

两个用于访问字符串中特定字符的方法:charAt() 和 charCodeAt()。这两个方法都接收一个参数,即基于0的字符位置。

其中,charAt() 方法以单字符串的形式返回给定位置的那个字符。

var stringValue = "hello world";
alert(stringValue.charAt(1)); // e

var stringValue = "hello world";
alert(stringValue.charCodeAt(1)); // 101

ECMAScript 5 还定义了另一个访问识别字符的方法:

var stringValue = "hello world";
alert(stringValue[1]); // e

字符串操作方法 concat()、slice()、substr()、substring()

concat()

用于将一或多个字符串拼接起来,并返回新的字符串

var stringValue = "hello ";
var result = stringValue.concat("world")
var result1 = stringValue.concat("world", '!')
alert(result); // hello world
alert(result1); // hello world!
alert(stringValue); // hello

实践中使用更多的还是加号操作符 (+)。而且,使用加号操作符在大多数情况下都比使用 concat() 方法要简便易行。

slice()、substr()、substring()

这三个方法都会返回被操作字符串的一个字字符串,而且也都接受一个或两个参数。

第一个参数指定字符串的开始位置,第二个参数(在指定的情况下)表示字符串到哪里结束。

slice() 和 substring() 的第二个参数指定的是字符串最后一个字符后面的位置。

substr() 的第二个参数指定的是返回的字符串个数。

如果没有给这些方法传递第二个参数,则将字符串的长度作为结束的位置。

与concat方法一样,slice()、substr()、substring() 也不会修改字符串本身的值 ---- 他们只是返回一个基本类型的字符串值,对原始字符串没有任何影响 。

var stringValue = "hello world";
alert(stringValue.slice(3)); // lo world
alert(stringValue.substring(3)); // lo world
alert(stringValue.substr(3)); // lo world

alert(stringValue.slice(3, 7)); // lo w
alert(stringValue.substring(3, 7)); // lo w
alert(stringValue.substr(3, 7)); // lo worl

在传递参数是负值的情况下,它们的行为就不尽相同了。

  • slice() 方法会将传入的负值与字符串的长度相加。
  • substr() 方法将负的第一个参数加上字符串的长度,而将负值的第二个参数转换为0。
  • substring() 方法会把所有负值参数都转换为0,这个方法会将较小的数作为开始位置,将较大的数作为结束位置。
var strubgValue = "hello world";
alert(stringValue.slice(-3)); // rld
alert(stringValue.substring(-3)); // hello world
alert(stringValue.substr(-3)); // rld

alert(stringValue.slice(3, -4)); // lo w;   相当于:stringValue.slice(3, 7)
alert(stringValue.substring(3, -4)); // hel;   相当于:stringValue.substring(3, 0)
alert(stringValue.substr(3, -4)); // ""(空字符串);   相当于:stringValue.substr(3, 0)

IE 的 JavaScript 实现在处理向 substr() 方法传递负值的情况时存在问题,它会返回原始的字符串。IE9 修复了这个问题

  1. 在只传入一个参数的情况:
  • 正数:

    • 使用 slice()、substr()、substring() 方法结果是相同的
  • 负数:

    • slice()、substr() 返回 (字符串长度 + 参数1)字符串结束位置 的字符,如果 参数1 小于0则表示从 0 开始到 字符串结束位置 的字符。
    • substring() 返回 0 开始到 字符串结束位置 的字符。
  1. 在传入两个参数的情况下 :
  • 参数2 正数:

    • slice()、substring() 返回从 参数1 的角标到 参数2 的角标之间的字符串
    • substr() 返回从 参数1 的角标到 (参数1 + 参数2) 角标的字符串
  • 参数2负数:

    • slice() 返回从 参数1(字符串长度 + 参数2) 的位置
    • substring() 返回从 0参数1的位置(该方法会把所有负值参数都转换为0,将较小的数作为开始位置,将较大的数作为结束位置)
    • substr() 返回从 参数10 的位置(该方法会将负值的第二个参数转换为0)

字符串位置方法 indexOf()、lastIndexOf()

从一个字符串中搜索给定的子字符串,然后返回字符串的位置(如果没有找到子字符串,则返回-1)。

indexOf() 方法从字符串的开头向后搜索子字符串,而 lastIndexOf() 方法是从字符串的末尾向前搜索字符串

var stringValue = "hello world";
alert(stringValue.indexOf("o")); // 4
alert(stringValue.lastIndexOf("o")); // 7

这两个参数可以接收第二个参数,表示从字符串中的哪个位置开始搜索(可以用于遍历搜索出所有匹配的字符串的位置)。

var stringValue = "hello world";
alert(stringValue.indexOf(("o", 6))); // 7
alert(stringValue.lastIndexOf(("o", 6))); // 4

使用indexOf() 或 lastIndexOf() 来找到所有匹配的字符串

var stringValue = "Lorem iosym dolor sit a met, consectetur adipisicing elit";

var positions = new Array();
var pos = stringValue.indexOf("e");

while ((pos > -1)) {
    positions.push(pos);
    pos = stringValue.indexOf("e", pos + 1);
}
alert(positions); // 3,25,33,36,53

trim()

ECMAScript 5 为所有字符串定义了 trim() 方法。这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果。

var stringValue = "   hello world   ";
var trimmedStringValue = stringValue.trim();
alert(stringValue); //    hello world   
alert(trimmedStringValue); // hello world

由于 trim() 返回的是字符串的副本,所以原始字符串中的前置及后缀空格会保持不变。

支持这个方法的浏览器有 IE9、Firefox 3.5+、Safari 5+、Opera 10.5+和chrome。

Firefox 3.5+、Safari 5+和chrome 8+ 还支持非标准的 trimLeft()和 trimRight() 方法,分别用于删除字符串开头和末尾的空格。

字符串大小写转换方法

ECMAScript 中涉及字符串大小写转换的方法有 4个:toLowerCase()、toLocaleLowerCase()、toUpperCase()、和toLocaleUpperCase()。

toLowerCase()、toUpperCase()是借鉴自 java.lang.String 中的同名方法。

toLocaleLowerCase()、和 toLocaleUpperCase() 方法是针对特定地区的实现。

var stringValue = "hello world";
alert(stringValue.toLocaleUpperCase()); // HELLO WORLD
alert(stringValue.toUpperCase()); // HELLO WORLD
alert(stringValue.toLocaleLowerCase()); // hello world
alert(stringValue.toLowerCase()); // hello world

字符串的模式匹配方法

String 类型定义了几个用于在字符串中匹配模式的方法。

  • match():在字符串上调用这个方法,本质上与调用 RegExp 的 exec() 方法相同。match() 方法只接受一个参数,要么是一个正则表达式,要么是一个 RegExp 对象。
var text = "cat,bat,sat,fat";
var pattern = /.at/;

// 与 pattern.exec(text) 相同
var matches = text.match(pattern);
alert(matches.index); // 0
alert(matches[0]); // cat
alert(pattern.lastIndex); // 0
  • search():这个方法的唯一参数与 match() 方法的参数相同,返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回 -1。search() 方法始终是从字符串开头向后查询的模式。
var text = "cat,bat,sat,fat";
var pos = text.search(/at/);
alert(pos); // 1

上例中的 search() 方法返回1,即 "at" 在字符串中第一次出现的位置。

  • replace():简化字符串操作,这个方法有两个参数。

    • 第一个参数可以是一个 RegExp 对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。
    • 如果第一个参数是字符串,那么只会替换第一个子字符串。
    • 要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(g)标志。
var text = "cat,bat,sat,fat";
var result = text.replace("at", "ond");

alert(result); // cond,bat,sat,fat

result = text.replace(/at/g, "ond");
alert(result); // cond,bond,sond,fond

replace() 方法的第二个参数也可以是一个函数。在只有一个匹配项的情况下,会向这个函数传递3个参数;模式的匹配项、模式匹配项在字符串中的位置和原始字符串。

在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第二个是捕获组的匹配项...,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串。

这个函数应该返回一个字符串,表示应该被替换的匹配项使用函数作为 replace() 方法的第二个参数可以实现更加精细的替换。

function htmlEscape(text) {
    return text.replace(/[<>"&"]/g, function(match, pos, originalText) {
        switch (match) {
            case "<":
                return '<';
            case ">":
                return '>';
            case "&":
                return '&apm;';
        }
    })
}

alert(htmlEscape("<p class=\"greeting\">Hello world!</p>")) // <p class=undefinedgreetingundefined>Hello world!</p>
  • split():这个方法可以基于指定的分隔符讲一个字符串分割成多个子字符串,并将结果放在一个数组中。分隔符可以是一个字符串,也可以是一个 RegExp 对象(这个方法不会将字符串看成正则表达式)。split() 方法可以接收可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会操作既定大小。
var colorText = "red,blue,green,yellow";
console.log(colorText.split(",")); // [red,blue,green,yellow]
console.log(colorText.split(",", 2)); // [red,blue]
console.log(colorText.split(/[^\,] +/, 2)); // ["red,blue,green,yellow"]

对 split() 中正则表达式的支持因浏览器而异。尽管对于简单的模式没有什么差别,但对于未发现匹配项以及带有捕获组的模式,匹配的行为就不大相同了。

  • IE8及之前版本会忽略捕获组。ECMA-262 规定应该把捕获组接到结果数组中。 IE9 能正确的在结果中包含捕获组。
  • Firefox 3.6 及之前版本在捕获组未找到匹配项时,会在结果数组中包含空字符串; ECMA-262 规定没有匹配项的捕获组在结果数组中应该用 undefined 表示。

在正则表达式中使用捕获组还有其他的微妙差别。在使用这种正则表达式时,一定要在各种浏览器下多做一些测试。

  • localeCompare():这个方法比较两个字符串,并返回下列值中的一个

    • 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1,具体的值要看实现而定);
    • 如果字符串等于字符串参数,则返回0;
    • 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(大多数情况下是1,具体的值要看实现而定);
    var stringValue = "yellow";
    alert(stringValue.localeCompare("brick")); // 1
    alert(stringValue.localeCompare("yellow")); // 0
    alert(stringValue.localeCompare("zoo")); // -1
    

    注意:因为返回的数字取决于实现,所以最好是以下列所示来使用这个方法

    function determineOrder(value) {
        var result = stringValue.localeCompare(value);
    
        if (result < 0) {
            alert('该字符串在比对的字符串之前');
        } else if ( result > 0) {
            alert('该字符串在比对的字符串之后');
        } else {
            alert('两个字符串相等');
        }
    }
    
    determineOrder("brick"); // 该字符串在比对的字符串之后
    determineOrder("yellow"); // 两个字符串相等
    determineOrder("zoo"); // 该字符串在比对的字符串之前
    
  • fromCharCode():这个方法的任务是接收一个或多个字符串编码,然后将它们转换成一个字符串。从本质上来看,这个方法与实例方法 charCodeAt() 执行的是相反的操作。

alert(String.fromCharCode(104, 101, 108,108, 111)); // hello
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,540评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,640评论 2 374
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,643评论 0 326
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,672评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,525评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,387评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,809评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,450评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,743评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,787评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,560评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,406评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,824评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,048评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,335评论 1 253
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,784评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,997评论 2 337

推荐阅读更多精彩内容