自学的教程
阮一峰老师的JavaScript标准参考教程:https://wangdoc.com/javascript/
1. 数据类型简介
2. JavaScript确定一个值的类型
一共有三种方法:
1)typeof运算符
2)instanceof运算符
3)Object.prototype.toString方法
typeof运算符
- 数值返回number;
- 字符串返回string;
- 布尔值返回boolean;
- 函数返回function;
function f() {}
typeof f
//"function"
- undefined返回 undefined:
typeof undefined
//"undefined"
利用这一点,可以检查一个没有声明的变量:
if(typeof v === "undefined"){
//...
}
- 对象返回object
typeof window //"object"
typeof [] //"object"
typeof {} //"object"
本质上,数组在JavaScript内部也是一种特殊的对象
- null返回object
(当前教程在本章节只介绍了typeof运算符的详细用法,其他两种后续再进行补充)
3. 数值
3.1 整数和浮点数
JavaScript内部没有整数,都是以64位浮点数进行存储,所以1和1.0是相同的:
1 === 1.0 //true
容易造成混淆的是,某些运算只有整数才能完成,此时JavaScript会自动把64位的浮点数转为32位的整数,然后再进行运算,具体会再后续章节再学习。
由于浮点数不是经确的值,所以涉及小数的比较和运算要特别小心:
0.1 + 0.2 === 0.3 //false
0.3 / 0.1 //2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1) //false
这样看来,如果运算中左右两个操作数都是浮点数,则可能达不到我们预想的结果,要特别注意。
3.2 数值精度
根据国际标准 IEEE 754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。
- 第1位:符号位,0表示正数,1表示负数
- 第2位到第12位(共11位):指数部分
- 第13位到第64位(共52位):小数部分(即有效数字)
符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。
JavaScript最大能处理绝对值位253,大于这个值,无论是做存储还是运算都不再精确。
3.3 数值范围
根据标准,64位浮点数的指数部分长度位11各二进制位,意味着指数部分的最大值是2047(211-1),也就是说64位浮点数的指数部分的最大值是2047,分出一半表示负数,则JavaScript能够表示的数值范围是21024到2-1023,超出这个范围无法表示。
1)正向溢出
如果一个数大于等于21024,那么就会发生“正向溢出”,会返回Infinity
Math.pow(2, 1024) //Infinity
2)负向溢出
如果一个数小于等于2-1075(指数部分最小值是-1023,再加上小数部分的52位),就会发生“负向溢出”,会直接返回0
Math.pow(2, -1075) //0
3)JavaScript提供Number对象的MAX_VALUE和MIN_VALUE,表示最大值和最小值
Number.MAX_VALUE //1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
3.4 数值表示
以下两种情况,JavaScript会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示:
1)小数点前面的数字多于21位
2)小数点后的零多于5个(0.0000003)
3.5 数值进制
- 十进制:没有前导0的数值
- 八进制:有前缀0o或00的数值,或者有前导0且只用到0-7八个阿拉伯数值的数值;
- 十六进制:有前缀0x或0X的数值
- 二进制:有前缀0b或0B的数值
默认,JavaScript内部会自动将其他进制转为十进制数
0xff //255
0o377 //255
0b11 //3
通常来说,有前导0的数值会被认为是八进制,但是如果前导0后面有大于等于8的值,则认为是十进制:
0888 //888
0777 //511
前导0表示八进制,处理时很容易造成混乱。ES5 的严格模式和 ES6,已经废除了这种表示法,但是浏览器为了兼容以前的代码,目前还继续支持这种表示法。
尽量不要用啦!!八进制表示用0o前缀就好了!
4. 特殊数值
1)NaN:
- NaN不等于任何值,包括它本身;
- NaN不是一种特殊的数据类型,typeof NaN为number,所以它知识一种特殊的数值而已;
- Boolean(NaN)是false.
2)Infinity:
- 有正负之分,Infinity !== -Infinity
- 0/0 NaN
- 1/0 Infinity
- 1/ -0 -Infinity
- 0 * Infinity NaN
- 0 / Infinity 0
- Infinity - Infinity NaN
5. 全局数值转换
5.1 parseInt()
1)如果字符串头部有空格,空格会被自动去除
2)如果parseInt的参数不是字符串,则会先转为字符串再转换
parseInt(1.23) //1
//等同于
parseInt("1.23") //1
3)字符串转为整数的时候,是一个个字符串一次转换,如果遇到不能转为数字的字符,则不再继续下去。
parseInt("8a") //8
//等同于
parseInt("12**") //12
4)如果字符串的第一个字符串不能转化为数字(后面跟着数字的正负号除外),返回NaN。
parseInt("abc") //NaN
//等同于
parseInt(".3") //NaN
parseInt('+1') //NaN
5)如果字符串以0x或0X开发,将其按16进制解析;
字符串以0 开头,将其按十进制解析;
6)进制转换:
parseInt方法可以接受第二个参数(2-36之间),表示解析值的进制,返回该值对应的十进制数。
parseInt("1000") //1000
parseInt("1000", 10) //1000
parseInt('1000', 2) //8
parseInt('1000', 6) //216
parseInt('1000', 8) //512
5.2 parseFloat()
与parseInt类似,是转换为浮点数
5.3 isNaN()
isNaN方法可以用来判断一个值是否为NaN:
isNaN只对数值有效,如果传入其他值,会被先转成数值。所以需要特别注意,也许参数并不是NaN而是字符串。
同样,对于对象和数组,isNaN也会返回true
isNaN('Hello') //true
//相当于
isNaN(Number('Hello')) //true
isNaN({}) //true
isNaN(['xyz']) //true
isNaN([]) //false
5.4 isFinite()
这个方法之前从未用过,可以返回一个布尔值,判断数值是否是正常的值,但是null值判断失败,也会返回true
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
isFinite(null) // true
isFinite(-1) // true
可以用于判断是否是NaN或undefined,所以是比较有用的
6. 字符串
6.1 定义
1) 单引号内部可以使用双引号,双引号内部,可以使用单引号;
2) 但是如果单引号内部有单引号,或双引号内部有双引号,就必须加转义字符
'Did she say \'Hello\'?'
// "Did she say 'Hello'?"
"Did she say \"Hello\"?"
// "Did she say "Hello"?"
- 字符串默认只能写在一行,分成多行会报错,如果长字符串必须分行,在每一行的末尾需要加反斜杠,注意,反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错.
var longStr = 'Long \
long \
long \
string';
6.2 字符串与数组
字符串内部的单个自负无法改变和增删,这些操作都会默默的失败
var s = 'hello';
delete s[0];
s // "hello"
s[1] = 'a';
s // "hello"
s[5] = '!';
s // "hello"
6.3 字符串length
这个属性是返回字符串的长度,该属性无法改变
var s = 'hello';
s.length //5
s.length = 3;
s.length //5
6.4 字符集
JavaScript使用Unicode字符集。
对于码点在U+10000到U+10FFFF之间的字符,JavaScript 总是认为它们是两个字符(length属性为2)。所以处理的时候,必须把这一点考虑在内,也就是说,JavaScript 返回的字符串长度可能是不正确的
6.5 Base64转码
使用场景:有时,文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。
所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+和/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。
(Base64之前在项目中为了加密使用过,但在js没有用过)
JavaScript 原生提供两个 Base64 相关的方法:
- btoa(): 任意值转为Base64编码
- atob(); Base64编码转为原来的值
var s = 'hello world!';
btoa(string); // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"
注意,这两个方法不适用于非ASCII码的自负,会报错
btoa('你好'); // 报错
要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法:
function b64Encode(str){
return btoa(encodeURIComponent(str));
}
function b64Decode(str){
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"