基本包装类型
我们会经常对基本类型值作如下操作:
var str = "string";
str.substring(2); // "ring"
基本类型不是对象,没有属性和方法,那substring()
是从哪里来的呢?
原来我们在执行第二行时,后台会自动完成如下过程:
var s1 = new String("string");
var s2 = s1.substring(2);
s1 = null;
Boolean类型
Boolean类型是与布尔值相对应的引用类型。
var falsy= new Boolean(false);
truth.valueOf(); // false
truth.toString(); // "false"
falsy&& true; // true
Boolean(falsy); //true
由于falsy
是一个对象,因此转化为布尔值时为true
Number 类型
Number类型是与数值对应的引用类型。
var num = 10;
num.valueOf(); //12
num.toString(); // "12"
num.toString(2); // "1100"
toFixed()
toFixed()
可以按照指定的小数位数返回数值的字符串表示,如果指定的小数位数小于原有位数,则四舍五入。
var num = 10.252;
num.toFixed(6); // "10.252000"
num.toFixed(2); // "10.25"
num.toFixed(1); // "10.3"
toExponential()
toExponential()
可以将数值转化为具有指定小数位数的科学技术法。
var num = 1234567;
num.toExponential(2); // "1.23e+6"
toPrecision()
toPrecision()
可以格式化数值,传入希望输出的数值位数(计算位数时不考虑指数)。
var num = 99;
num.toPrecision(1); // "1e+2"
num.toPrecision(3); // "99.0"
String 类型
String
类型是与字符串相对应的引用类型。
var str = "string";
str.toString(); // "string"
str.valueOf(); // "string"
str.length; // 6
每个String
实例都有length
属性,表示一个字符串中包含的字符量,注意字符串中的双字节字符视为一个字符。
访问特定位置的字符
-
charAt()
接受一个参数,表示要访问的字符在字符串中基于0的位置,返回指定位置的单字符字符串(ECMAScript中没有单字符类型)
var str = "name";
console.log(str.charAt(2)); // "m"
charCodeAt()
接受一个参数,表示要访问的字符在字符串中基于0的位置,返回指定位置的字符对应的字符编码字符串(ECMAScript中没有单字符类型)
var str = "name";
console.log(str.charCodeAt(2)); // "109"
-
[]
在IE8、Firefox、Safari、Chrome、Opera浏览器中,还支持方括号访问个别字符的语法:
var str = "name";
console.log(str[2]); // "m"
字符串操作方法
-
concat()
用于将一个或多个字符串拼接起来形成一个新的字符串。
var str1 = "Hello";
var str2 = "World";
str1.concat(" ", str2, "!"); // "Hello World"
str1; // "Hello"
-
+
与concat
的功能相同,但更加简便。
"Hello" + " " + "World" + "!"; // "Hello World"
-
slice()
substr()
substring()
这三个方法都可以基于子字符串返回新字符串,都接受1个或2个参数,第一个都表示子字符串的起始位置,slice()
和substring()
的第二个参数指定子字符串最后一个字符后面的位置,substr
的第二个参数指定的是字符个数,这三个方法对原始字符串不会产生影响。
var str = "Hello World!";
console.log(str.slice(3)); // "lo World!"
console.log(str.substr(3)); // "lo World!"
console.log(str.substring(3)); // "lo World!"
console.log(str.slice(3, 6)); // "lo "
console.log(str.substr(3, 6)); // "lo Wor"
console.log(str.substring(3, 6)); // "lo "
以上的例子传入的参数均是正值,如果传入负值,它们的表现就不会那么一致了。
var str = "Hello World!";
console.log(str.length);
console.log(str.slice(-3)); // "ld!" -3 被转换成9
console.log(str.slice(9)); // "ld!"
console.log(str.substr(-3)); //"ld!" -3 被转换成9
console.log(str.substr(-3)); // "ld!"
console.log(str.substring(-3)); // "Hello World!" -3被转换成0
console.log(str.substring(0)); // "Hello World!"
console.log(str.slice(3, -8)); / / "l" -8 被转换为4
console.log(str.slice(3, 5)); // "l"
console.log(str.substr(3, -8)); // "" -8 被转换为0
console.log(str.substr(3, -8)); // ""
console.log(str.substring(3, -10)); // "Hel" -10被转化为0,由于0<3,0成为第一参数
console.log(str.substring(0, 3)); // "Hel"
如果slice()
的参数为负值,它会使用字符串长度与它们相加,如果相加后的结果为正,则返回相应子字符串,如果结构为负,则转换为0。
substr()
与slice()
对待第一个参数的方式相同,当substr()
的第二个参数也为负值时,它会直接将这个负值转换为0。
substring
会将小于0的参数都转换为0,然后比较两个参数的大小,最后将较小的参数作为第一个参数,较大的参数作为第二个参数。
-
trim()
创建一个字符串的副本(不影响原字符串),删除前置和后缀空格。
IE 9+、Safari 5+、Firefox 3.5+、Opera 10.5+、Chrome都支持这个方法,chrome 8+、Firefox 3.5+、Safari 5+还支持trimLeft()
和trimRight()
,分别用于删除字符串开头和末尾的空格。
访问指定位置的字符串
-
indexOf(str, index)
从字符串开头搜索给定字符串str
,返回子字符串的位置,如果没有搜到,返回-1,index
表示开始搜索的位置。 -
lastIndexOf(str, index)
从字符串尾部搜索给定字符串str
,返回子字符串的位置,如果没有搜到,返回-1,index
表示开始搜索的位置。
书中提到了一个可以遍历字符串,找到所有匹配子字符串的方法:
var str = "abcdabcabcdefabcddabcedfsd";
var position = new Array();
var pos = str.indexOf("d");
while(pos > -1) {
position.push(pos);
pos = str.indexOf("d", pos + 1);
}
console.log(position); // [3, 10, 16, 17, 22, 25]
大小写转换
toLowerCase()
toUpperCase()
toLocaleUpperCase()
toLocaleLowerCase()
模式匹配
-
match()
与之前提到过的RegExp.exec()
本质是一样的,接受的参数要么是正则表达式,要么是RegExp
对象,返回一个数组,数组第一项是匹配项,之后是捕获组匹配的字符串。
var str = "abcdabc";
var pattern = /ab(c)/;
str.match(pattern); // ["abc", "c", index: 0, input: "abcdabc"]
-
seach()
接收正则表达式或RegExp
对象,返回字符串中从开头查找到的第一个匹配项的索引,如果找不到,返回-1。
var str = "abc";
var pattern = /a/;
str.search(pattern); // 0
-
replace()
接受两个参数,第一个表示需要匹配的字符串或正则表达式,第二个表示要替换成的内容,可以是字符串或函数,如果第一个参数是字符串,只会替换掉第一个匹配的内容,如果要替换所有匹配的内容,应该使用正则表达式,并加添加g
标志。返回被替换后的字符串,不改变原字符串。
var str = "abcabcdabdabe";
str.replace("abc", "abcd"); //"abcdabcdabdabe"
str.replace(/abc/g, "a");
- 如果第二个参数是字符串
此时,不仅可以使用普通字符串来替换第一个参数匹配到的内容,也可以使用一些特殊的字符序列,将正则表达式得到的值插入到结果字符串中。
字符序列 | 替换文本 |
---|---|
$$ | $ |
$& | RegExp.lastMatch |
$' | RegExp.leftContext |
$` | RegExp.rightContext |
$n | 第n个捕获组的字符串 |
$nn | 第nn个捕获组的字符串 |
举一些例子:
var str = "cat, bat, sat, fat";
result = str.replace(/(.at)/g, "word ($1)")
"word (cat), word (bat), word (sat), word (fat)"
result = str.replace(/(.at)/g, "word ($')")
"word (, bat, sat, fat), word (, sat, fat), word (, fat), word ()"
result = str.replace(/(.at)/g, "word ($`)")
"word (), word (cat, ), word (cat, bat, ), word (cat, bat, sat, )"
result = str.replace(/(.at)/g, "word ($$)")
"word ($), word ($), word ($), word ($)"
result = str.replace(/(.at)/g, "word ($&)")
"word (cat), word (bat), word (sat), word (fat)"
result = str.replace(/(b)(at)/g, "word ($2)")
"cat, word (at), sat, fat"
- replace() 方法的第二个参数可以是函数。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在原字符串中出现的位置。最后一个参数是原字符串本身。
书中提到了一个例子:
function htmlEscape(text){
return text.replace(/[<>"&]/g,
function(match, pos, originalText){
switch(match){
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
case "\"":
return """;
}
});
}
alert(htmlEscape("<p class=\"greeting\">Hello world!</p>"));
//<p class="greeting">Hello world!</p>
W3C中还有一个例子,可以将所有单词的首字母转化为大写:
name = 'aaa bbb ccc';
uw=name.replace(/\b\w+\b/g, function(word){
return word.substring(0,1).toUpperCase()+word.substring(1);}
);
通过第三个参数,我们可以使用不同的转义序列分别替代<
>
&
\
-
split()
将一个字符串基于指定分隔符分割成多个子字符串,返回子字符串构成的数组,第一个参数作为分隔符,可以是字符串,也可以是正则表达式,第二个参数可选,指定数组大小。
var str = "Hat, Bat, Rat, Cat";
str.split();
//["Hat, Bat, Rat, Cat"]
str.split(",");
//(4) ["Hat", " Bat", " Rat", " Cat"]
str.split(",", 2);
//(2) ["Hat", " Bat"]
str.split(/at/);
//(5) ["H", ", B", ", R", ", C", ""]
字符串比较方法
localeCompare()用于比较两个字符串:
strA.localeCompare(strB)
如果strA < strB
,返回一个负数(不一定是-1);
如果strA > strB
,返回一个正数(不一定是1);
如果strA == strB
,返回0。
localeCompare()的比较方法因地区而异。
fromCharCode()
String构造函数中的静态方法,接受一个或多个字符编码,将它们转换成字符串。
String.fromCharCode(33, 23, 3); //!��
HTML方法
下面的例子列举了可以生成标准HTML标签的方法:
var str = "Hello World!"
str.anchor("welcome"); //<a name="welcome">Hello World!</a>
str.big(); //<big>Hello World!</big>
str.bold(); //<b>Hello World!</b>
str.fixed(); //<tt>Hello World!</tt>
str.fontcolor("red"); //<font color="red">Hello World!</font>
str.fontsize(12); //<font size="12">Hello World!</font>
str.italics(); //<i>Hello World!</i>
str.link("www.jianshu.com"); //<a href="www.jianshu.com">Hello World!</a>
str.small(); //<small>Hello World!</small>
str.strike(); //<strike>Hello World!</strike>
str.sub(); //<sub>Hello World!</sub>
str.sup(); //<sup>Hello World!</sup>
内置对象
Global
所有全局作用域的属性和函数都是Global对象的属性
encodeURI()
和encodeURIComponent()
这两个编码方法可以使用UTF-8对URI进行编码,当我们的URI中包含某些无效字符时,可以使用这两个方法将URI转换成浏览器可以识别的字符串。
encodeURI()
- 编码范围
ASCII字母、数字、~!@#$&*()=:/,;?+'
之外的字符。 - 例子
encodeURI("http://www.baidu.com/some other thing");
"http://www.baidu.com/some%20other%20thing"
可以看出,encodeURI()
将空格转化为%20
,返回一个可以直接被浏览器识别的URI。
encodeURIComponent()
- 编码范围
ASCII字母、数字、~!*()'
之外的字符。 - 例子
encodeURIComponent("http://www.baidu.com/some other thing");
"http%3A%2F%2Fwww.baidu.com%2Fsome%20other%20thing"
可以看出encodeURIComponent()
将空格、:
、 /
都进行了编码,然而返回的结果似乎是一个不可用的URI,那么这个方法有什么用呢?
假如说我们要访问如下URI:
https://www.baidu.com/s?://
如果不进行编码,浏览器会将所有的反斜杠都视为分隔符,这显然不是我们的初衷。这种情况下,我们应对://
进行编码。
var baseURI = "https://www.baidu.com/s?wd=";
var s = encodeURIComponent("://");
var uri = baseURI + s;
console.log(uri); //https://www.baidu.com/s?wd=%3A%2F%2F
decodeURI()
和 decodeURIComponent()
有编码自然就有解码,decodeURI()
只能解码encodeURI()
处理过的字符串,而decodeURIComponent()
则可以解码任何特殊字符的编码。
还是上述的例子:
decodeURI(uri)
"https://www.baidu.com/s?wd=%3A%2F%2F"
decodeURIComponent(uri)
"https://www.baidu.com/s?wd=://"
eval
只接受一个参数,可执行的Javascript字符串。解析器遇到eval()
时,会将参数当作实际的ECMAScript语句来解析,并且eval()
中的代码被纳入调用eval()
的执行环境中。
var message = "hello";
eval("message += ' world!'; function say(){ console.log(message);}")
say();
hello world!
书中提到在eval()
中创建的变量和函数不会被提升。但笔者试了一下,发现不是这样:
eval("var tt='aa'; function test(){console.log(tt); var tt='dd'; console.log(tt);} test();")
// undefined dd
eval("test(); function test(){var tt='dd'; console.log(tt);}")
// dd
test();
eval("function test(){var tt='dd'; console.log(tt);}")
//undefined
严格模式下,外部访问不到eval()
中创建的函数和变量,也不可以为eval
赋值。
Global对象的其他函数
isNaN()、isFinite()、parseInt()以及parseFloat()等。
Global对象的属性
- 值
undefined
NaN
Infinity
- 构造函数
Object
Array
Function
Boolean
String
Number
Date
RegExp
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
window
Web浏览器中,Global对象中的变量和函数都是window对象的属性
Math
Math对象的属性
属性 | 说明 |
---|---|
Math.E |
e |
Math.LN10 |
10的自然对数 |
Math.LN2 |
2的自然对数 |
Math.LOG2E |
以2为底的e的对数 |
Math.LOG10E |
以10为底的e的对数 |
Math.PI |
π |
Math.SQRT1_2 |
1/2的平方根 |
Math.SQRT2 |
2的平方根 |
min()
和max()
接受多个数值参数,得到其中的最大、最小值。
如果我们要从一个数值数组中获得最大最小值呢?可以使用apply
:
var array = [4, 5, 7, 1, 3, 10, 6];
Math.max.apply(Math, array)
//10
需要注意的是,要将Math
作为max()
的this
。
舍入方法
-
Math.ceil()
:向上舍入 -
Math.round()
:四舍五入 -
Math.floor()
:向下舍入
var num1 = 24.5, num2 = 24.4;
Math.ceil(num1); // 25
Math.floor(num1); // 24
Math.round(num1); // 25
Math.round(num2); // 24
random
返回一个大于等于0小于1的随机数。书中提到了一个从某个整数范围内随机选择一个值的方法:
value = Math.floor(Math.random() * range + minValue)
比如返回一个1到10中的一个随机整数:
var num = Math.floor(Math.random() * 10 + 1)
其他方法
方法 | 说明 |
---|---|
Math.abs(num) |
返回num 的绝对值 |
Math.exp(num) |
返回Math.E 的num 次幂 |
Math.log(num) |
返回num 的自然对数 |
Math.pow(num, power) |
返回num 的power 次幂 |
Math.sqrt(num) |
返回num 的平方根 |
Math.acos(x) |
返回x 的反余弦值 |
Math.asin(x) |
返回x 的反正弦值 |
Math.atan(x) |
返回x 的反正切值 |
Math.atan2(y, x) |
返回y/x 的反正切值 |
Math.cos(x) |
返回x 的余弦值 |
Math.sin(x) |
返回x 的正弦值 |
Math.tan(x) |
返回x 的正切值 |
网友评论