《JavaScript 闯关记》之核心包装档次

为便利操作基本类型值,JavaScript
还提供了3只独特的援类型:BooleanNumber
String。实际上,每当读取一个基本类型值的时,后台就会见创一个遥相呼应的为主包装档次的靶子,从而让我们能够调用一些艺术来操作这些数据。来拘禁下的事例。

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

是例子中的变量 s1
包含一个字符串,字符串当然是基本类型值。而下一行调用了 s1
substring() 方法,并以回来的结果保存在了 s2
中。我们掌握,基本项目值未是目标,因而起逻辑上摆她不应当产生主意(尽管如我们所愿意,它们确实来措施)。其实,为了给我们实现这种直观的操作,后台就自行完成了同样多样之处理。当次行代码访问
s1
时,访问过程处于同一种读取模式,也就算是只要由内存中读取这个字符串的价值。而于读取模式遭遇走访字符串时,后台还见面自行就下列处理。

  1. 创建 String 类型的一个实例;
  2. 每当实例上调用指定的法门;
  3. 销毁之实例。

好以以上三只步骤想象变为是执行了下列 JavaScript 代码。

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

经过此番拍卖,基本的字符串值就换得与对象同了。而且,上面就三独步骤为独家适用于
BooleanNumber 类型对应的布尔值和数字值。

援类型及主导包装档次的关键区别就是是目标的生存期。使用 new
操作符创建的援类型的实例,在尽流离开当前作用域之前还直接保存在内存中。而自动创建的着力包装档次的目标,则仅仅设有于一行代码的履行瞬间,然后马上叫销毁。这代表我们不可知当运作时为核心类型值加加属性和方。来拘禁下的例子:

var s1 = "some text";
s1.color = "red";
console.log(s1.color);   // undefined

本,可以显式地调用 BooleanNumberString
来创建基本包装档次的对象。不过,应该当切必要的景下再也如此做,因为这种做法很容易被人口分开不清自己是于拍卖「基本型」还是「引用类型」的价值。对中心包装档次的实例调用
typeof 会返回 "object",而且富有中心包装档次的目标都见面受转换为布尔值
true

Object
构造函数也会见如工厂方法一致,根据传入值的种返回相应基本包装档次的实例。例如:

var obj = new Object("some text");
console.log(obj instanceof String);   // true

将字符串传于 Object 构造函数,就见面创 String
的实例;而传播数值参数会获取 Number 的实例,传入布尔值参数就会见得
Boolean 的实例。

使小心的凡,使用 new
调用基本包装档次的构造函数,与直调用同名的转型函数是匪相同的。 例如:

var value = "25";
var number = Number(value);  // 转型函数
console.log(typeof number);  // "number"

var obj = new Number(value); // 构造函数
console.log(typeof obj);     // "object"

尽管我们无建议显式地创建基本包装档次的目标,但她操作基本类型值的力或相当重要的。而每个中心包装档次且提供了操作相应值的省心措施。

Boolean 类型

Boolean 类型是与布尔值对应的援类型。要创 Boolean
对象,可以像下这样调用 Boolean 构造函数并传 truefalse 值。

var booleanObject = new Boolean(true);

Boolean 类型的实例更写了 valueOf() 方法,返回基本项目值 true
false;重写了 toString() 方法,返回字符串 "true"
"false"。可是,Boolean 对象在 JavaScript
中之用途不特别,因为它经常会面促成人们的误解。其中最为常见的题目不怕是当布尔表达式中应用
Boolean 对象,例如:

var falseObject = new Boolean(false);
var result = falseObject && true;
console.log(result);  // true

var falseValue = false;
result = falseValue && true;
console.log(result);  // false

于这事例中,我们以 false 值创建了一个 Boolean
对象。然后,将是目标和中心类型值 true
构成了逻辑与表达式。在布尔运算中,false && true 等于
false。可是,示例中之及时行代码是对准 falseObject 而不是对她的值 false
进行求值。布尔表达式中之保有目标还见面于转换为 true,因此 falseObject
对象在布尔表达式中象征的凡 true。结果,true && true 当然就相当于
true 了。

主导项目及援类型的布尔值还有个别单界别。首先,typeof
操作符对骨干项目返回 "boolean",而针对援类型返回
"object"。其次,由于 Boolean 对象是 Boolean 类型的实例,所以采用
instanceof 操作符测试 Boolean 对象见面返回
true,而测试中心类型的布尔值则归 false。例如:

console.log(typeof falseObject);   // object
console.log(typeof falseValue);    // boolean
console.log(falseObject instanceof Boolean);  // true
console.log(falseValue instanceof Boolean);   // false

了解基本项目的布尔值与 Boolean
对象期间的分非常主要,我们的建议是永恒不要使 Boolean 对象。

Number 类型

Number 是与数字值对应的援类型。要开创 Number 对象,可以于调用
Number 构造函数时向里面传递相应的数值。下面是一个事例。

var numberObject = new Number(10);

Boolean 类型一样,Number 类型也重写了
valueOf()toLocaleString()toString() 方法。重写后底
valueOf()
方法返回对象表示的基本类型的数值,另外两独艺术虽然回字符串形式之数值。可以为
toString()
方法传递一个象征基数的参数,告诉她回到几进制数值的字符串形式,如下面的例子所示。

var 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"

除了继续的法之外,Number
类型还提供了一些用来将数值格式化为字符串的措施。其中,toFixed()
方法会按照指定的稍数位返回数值的字符串表示,例如:

var num = 10;
console.log(num.toFixed(2));    // "10.00"

这里给 toFixed() 方法传入了累值
2,意思是展示几乎各小数。于是,这个法子返回了 "10.00",即以 0
填补了必不可少的稍数各类。如果数值本身富含的微数各项比指定的尚差不多,那么看似指定的极充分小数位的值就是见面舍入,如下面的事例所示。

var num = 10.005;
console.log(num.toFixed(2));    // "10.01"

克活动舍入的风味,使得 toFixed() 方法很符合处理货币值。

可是需专注的凡,不同浏览器被此措施设定的舍入规则可能会见迥然不同。

在给 toFixed() 传入0的情事下,IE8
及之前版本不能够正确舍入范围以{(-0.94,-0.5],[0.5,0.94)}之间的价。对于这范围外之值,IE8
会回去回0,而无是-1还是1;其他浏览器都能回来正确的值。IE9 修复了之题材。

toFixed()
方法好代表带有0到20个小数位的数值。但迅即只是是规范落实之范围,有些浏览器为恐怕支持更多位数。

此外可用来格式化数值的方是
toExponential(),该方式返回以指数表示拟(也称 e
表示法)表示的数值的字符串形式。与 toFixed() 一样,toExponential()
也接到一个参数,而且该参数同样为是指定输出结果丁之小数位数。看下的例证。

var num = 10;
console.log(num.toExponential(1));     // "1.0e+1"

以上代码输出了 "1.0e+1";不过,这么小的数值一般不要下 e
表示法。如果您想赢得代表有数值的无限当的格式,就相应使
toPrecision() 方法。

于一个数值来说,toPrecision()
方法或者会见回固定大小(fixed)格式,也恐怕回指数(exponential)格式;具体规则是圈哪种格式最确切。这个法接收一个参数,即表示数值的具有数字之位数(不包指数部分)。请看下的例证。

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

如上代码首先得的天职是坐平等员数来代表 99,结果是 "1e+2",即
100。因为平号数无法精确地代表 99,因此 toPrecision()
就拿其发展舍入为
100,这样即使好行使同一个数来代表它了。而连下去的之所以鲜位数表示
99,当然还是 "99"。最后,在纪念为三各项数表示 99 时,toPrecision()
方法返回了 "99.0"。实际上,toPrecision()
会根据要拍卖的数值决定到底是调用 toFixed() 还是调用
toExponential()。而立三单方法还好通过提高或朝下舍入,做到以无比精确的花样来表示带有正确小数个之价。

toPrecision()
方法可以呈现1顶21号小数。但这只有是业内落实的界定,有些浏览器为或支持再次多位数。

Boolean 对象类似,Number
对象啊从此台措施为数值提供了关键之法力。但同时,我们还不建议直接实例化
Number 类型,而因及显式创建 Boolean 对象同。具体来讲,就是在使
typeofinstanceof
操作符测试中心型数值及援类型数值时,得到的结果完全不同,如下面的例证所示。

var numberObject = new Number(10);
var numberValue = 10;
console.log(typeof numberObject);   // "object"
console.log(typeof numberValue);    // "number"
console.log(numberObject instanceof Number);  // true
console.log(numberValue instanceof Number);   // false

String 类型

String 类型是字符串的目标包装档次,可以像下这样使 String
构造函数来创造。

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

String 对象的计吗可以具有骨干的字符串值中访问到。其中,继承的
valueOf()toLocaleString()toString()
方法,都回到对象所表示的中心字符串值。

String 类型的每个实例都产生一个 length
属性,表示字符串中富含多独字符。来拘禁下的例子。

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

应注意的是,即使字符串中富含对许节约字符(不是霸占一个字节的 ASCII
字符),每个字符也照样算一个字符。例如:

var stringValue = "大家好";
console.log(stringValue.length);     // 3

String 类型提供了诸多道,用于扶持完成对 JavaScript
中字符串的分析和操作。

字符方法

点滴独用于访问字符串中一定字符的办法是:charAt()
charCodeAt()。这简单只方式都接受一个参数,即基于0的字符位置。其中,charAt()
方法为仅字符字符串的款式返回给定位置的异常字符(JavaScript
中从不字符类型)。例如:

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

若你想取得的未是字符而是字符编码,那么就是如像下这样以
charCodeAt() 了。例如:

var stringValue = "hello world";
console.log(stringValue.charCodeAt(1));  // 101,101是小写字母"e"的字符编码

ECMAScript 5
还定义了其它一个访个别字符的办法。在支持浏览器被,可以采用方括号加数字索引来访问字符串中的特定字符,如下面的例证所示。

var stringValue = "hello world";
console.log(stringValue[1]);   // "e"

字符串操作方法

下介绍与操作字符串有关的几个艺术。第一单就是是
concat(),用于将平或者多独字符串拼接起来,返回拼接得到的新字符串。先来拘禁一个例。

var stringValue = "hello ";
var result = stringValue.concat("world");

console.log(result);        // "hello world"
console.log(stringValue);   // "hello"

实际上,concat()
方法可领任意多个参数,也就是说可以经过它拼接任意多单字符串。再看一个例:

var stringValue = "hello ";
var result = stringValue.concat("world", "!");

console.log(result);        // "hello world!"
console.log(stringValue);   // "hello"

虽然 concat()
是专程为此来拼接字符串的法门,但施行着使用更多之尚是加号操作符 +
。而且,使用加号操作符 + 在多数情况下还比使用
concat()方法要方便易行(特别是在拼接多独字符串的情下)。

JavaScript
还提供了三只因子字符串创建新字符串的方法:slice()substr()
substring()。这三只点子都见面回给操作字符串的一个子字符串,而且为还接受平等或者少数个参数。第一单参数指定子字符串的发端位置,第二只参数(在指定的图景下)表示子字符串到乌了。具体来说,slice()
substring() 的第二只参数指定的是子字符串最后一个字符后面的职。而
substr()
的第二只参数指定的虽是回的字符个数。如果没有让这些方式传递第二个参数,则以字符串的长度作为完结位置。与
concat() 方法同样,slice()substr()
substring()啊未会见修改字符串本身的价,它们只是返回一个为主型的字符串值,对原始字符串没有其他影响。请圈下面的例子。

var stringValue = "hello world";
console.log(stringValue.slice(3));            // "lo world"
console.log(stringValue.substring(3));        // "lo world"
console.log(stringValue.substr(3));           // "lo world"
console.log(stringValue.slice(3, 7));         // "lo w"
console.log(stringValue.substring(3,7));      // "lo w"
console.log(stringValue.substr(3, 7));        // "lo worl"

当传递给这些主意的参数是负值的情事下,它们的所作所为即便不尽相同了。其中,slice()
方法会将盛传的负值与字符串的长相加,substr()
方法以依靠的首先只参数加上字符串的长短,而以负的次只参数转换为0。最后,substring()
方法会把有负值参数都变为0。下面来拘禁例子。

var stringValue = "hello world";
console.log(stringValue.slice(-3));           // "rld"
console.log(stringValue.substring(-3));       // "hello world"
console.log(stringValue.substr(-3));          // "rld"
console.log(stringValue.slice(3, -4));        // "lo w"
console.log(stringValue.substring(3, -4));    // "hel"
console.log(stringValue.substr(3, -4));       //""(空字符串)

字符串位置方法

产生个别独好起字符串中查找子字符串的道:indexOf()
lastIndexOf()。这有限个措施都是于一个字符串中搜寻给定的子字符串,然后返子字符串的位置(如果无找到该子字符串,则归-1)。这点儿独主意的别在:indexOf()
方法从字符串的开为后搜索子字符串,而 lastIndexOf()
方法是由字符串的末尾向前搜索子字符串。还是来拘禁一个例子吧。

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

立马有限个措施都可吸纳可摘的第二单参数,表示于字符串中之哪位位置上马寻找。换句话说,indexOf()会打该参数指定的职为后找,忽小该位置之前的有所字符;而lastIndexOf()则会自指定的职位上搜索,忽小该职位然后的兼具字符。看下面的例子。

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

每当运第二个参数的动静下,可以通过循环调用 indexOf()
lastIndexOf() 来找到有匹配的子字符串,如下面的事例所示:

var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var positions = new Array();
var pos = stringValue.indexOf("e");

while(pos > -1){
    positions.push(pos);
    pos = stringValue.indexOf("e", pos + 1);
}
console.log(positions);    // "3,24,32,35,52"

trim() 方法

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

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

字符串大小写转换方法

JavaScript
中关系字符串大小写转换的艺术发生4单:toLowerCase()toLocaleLowerCase()toUpperCase()
toLocaleUpperCase()。其中,toLowerCase()toUpperCase()
是少数只经典的方式,借鉴自 java.lang.String 中之同名方法。而
toLocaleLowerCase()toLocaleUpperCase()
方法则是对准一定地区的实现。对有些地方来说,针对地方的章程及那通用方获得的结果一致,但个别言语(如土耳其语)会吗
Unicode
大小写转换应用特别之平整,这时候就必须使对所在的措施来确保落实科学的转换。以下是几乎单例证。

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

一般的话,在非理解自己之代码用在啊种语言环境中运作的动静下,还是以对所在的法门重复稳当一些。

字符串的模式匹配方法

String 类型定义了几独用于在字符串中相当模式之道。第一个方法就是是
match(),在字符串上调用这个方法,本质上和调用 RegExpexec()
方法一致。match() 方法只有领一个参数,要么是一个正则表达式,要么是一个
RegExp 对象。来拘禁下面的例证。

var text = "cat, bat, sat, fat"; 
var pattern = /.at/;

// 与pattern.exec(text)相同
var matches = text.match(pattern);
console.log(matches.index);               // 0
console.log(matches[0]);                  // "cat"
console.log(pattern.lastIndex);           // 0

另一个用于查找模式之主意是 search()。这个方式的唯一参数与 match()
方法的参数相同:由字符串或 RegExp 对象指定的一个正则表达式。search()
方法返回字符串中率先独门当户对配项的目;如果无找到匹配项,则归-1。而且,search()
方法始终是自字符串开头为后搜索模式。看下面的事例。

var text = "cat, bat, sat, fat"; 
var pos = text.search(/at/);
console.log(pos);   // 1,即"at"第一次出现的位置

为简化替换子字符串的操作,JavaScript 提供了 replace()
方法。这个艺术接受两个参数:第一单参数可以是一个 RegExp
对象要一个字符串(这个字符串不见面吃更换成正则表达式),第二只参数可以是一个字符串或者一个函数。如果第一个参数是字符串,那么单纯见面交替第一单子字符串。要惦记替换所有子字符串,唯一的点子就是是提供一个正则表达式,而且只要指定全局
g 标志,如下所示。

var text = "cat, bat, sat, fat"; 
var result = text.replace("at", "ond");
console.log(result);    // "cond, bat, sat, fat"

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

终极一个以及模式匹配有关的方是
split(),这个措施可以根据指定的相间符将一个字符串分割成多独子字符串,并将结果在一个数组中。分隔符可以是字符串,也可是一个
RegExp 对象(这个点子不会见将字符串看成正则表达式)。split()
方法可以接受可选的亚独参数,用于指定数组的轻重,以便确保归的数组不见面超越既定大小。请圈下面的例证。

var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(",");          // ["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2);       // ["red", "blue"]

localeCompare() 方法

此点子较简单个字符串,并返回下列值中的一个:

  • 假设字符串在字母表中应当解除在字符串参数之前,则赶回一个负数(大多数场面下是-1,具体的价值如果顾落实而定);
  • 若是字符串等于字符串参数,则赶回回0;
  • 万一字符串在字母表中该排除在字符串参数后,则归一个正数(大多数景下是1,具体的值同样要看落实而定)。

下是几个例子。

var stringValue = "yellow";       
console.log(stringValue.localeCompare("brick"));    // 1
console.log(stringValue.localeCompare("yellow"));   // 0
console.log(stringValue.localeCompare("zoo"));      // -1

此事例比较了字符串 "yellow" 和另外几只价:"brick""yellow"
"zoo"。因为 "brick" 在字母表中排在 "yellow" 之前,所以
localeCompare() 返回了1;而 "yellow" 等于 "yellow",所以
localeCompare() 返回了0;最后,"zoo" 在字母表中排在 "yellow"
后面,所以 localeCompare() 返回了-1。再强调平等次,因为
localeCompare()
返回的数值在实现,所以极是如下例子所展示之如此用此点子。

function determineOrder(value) {
    var result = stringValue.localeCompare(value);
    if (result < 0){
        console.log("The string 'yellow' comes before the string '" + value + "'.");
    } else if (result > 0) {
        console.log("The string 'yellow' comes after the string '" + value + "'.");
    } else {
        console.log("The string 'yellow' is equal to the string '" + value + "'.");
    }
}

determineOrder("brick");
determineOrder("yellow");
determineOrder("zoo");

采用这种组织,就好包好的代码在另实现着都得正确地运行了。

localeCompare()
方法比较特别之地方,就是落实所支持的地区(国家以及言语)决定了这个点子的所作所为。比如,美国坐英语作为
JavaScript 实现之正式语言,因此 localeCompare()
就是别轻重缓急写的,于是很写字母在字母表中排在小写字母前头就成了千篇一律桩决定性的于规则。不过,在另外地面或者即使不是这种情景了。

fromCharCode() 方法

另外,String
构造函数本身还有一个静态方法:fromCharCode()。这个艺术的天职是收到一要多只字符编码,然后拿其转换成一个字符串。从本质上来拘禁,这个主意及实例方法
charCodeAt() 执行之是倒转的操作。来拘禁一个例证:

console.log(String.fromCharCode(104, 101, 108, 108, 111)); // "hello"

var s = 'hello';
for(let i=0;i<s.length;i++){
  console.log(`${s[i]}----${s[i].charCodeAt()}`);
}
/*
"h----104"
"e----101"
"l----108"
"l----108"
"o----111"
*/

在这里,我们给 fromCharCode() 传递的是字符串 "hello"
中每个字母之字符编码。

关卡

// 挑战一
var falseObject = new Object(false);
console.log(typeof falseObject);             // ???
console.log(falseObject instanceof Object);  // ???
console.log(falseObject instanceof Boolean); // ???

// 挑战二
var numberObject = new Object(100);
console.log(typeof numberObject);             // ???
console.log(numberObject instanceof Object);  // ???
console.log(numberObject instanceof Number);  // ???

// 挑战三
var stringObject = new Object("abcde");
console.log(typeof stringObject);             // ???
console.log(stringObject instanceof Object);  // ???
console.log(stringObject instanceof String);  // ???

// 挑战四,翻转一个字符串
// 提示:可以使用数组的 reverse() 方法
var reverse = function(str) {
    // 待实现方法体
}
console.log(reverse("hello"));  // "olleh"

更多

关怀微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注
https://github.com/stone0090/javascript-lessons,获取最新动态。