基本分类
- 基本数据类型:undefined、null、boolean、number、string。
- 复杂数据类型:object(广义的对象)
1. typeof 操作符
-
typeof
是一个操作(运算)符,不是函数。 -
typeof
运算符可以返回一个值的数据类型,如:typeof 123 // "number" typeof '123' // "string" typeof false // "boolean" typeof undefined // "undefined" typeof null // "object" typeof {} // "object" typeof [] // "object" typeof NaN // 'number' function f() {} typeof f // "function"
2. Undefined 类型
- Undefined 类型只有一个值"
undefined
"。 - 对未初始化和未声明的变量执行
typeof
都返回 undefined。 - 函数没有返回值时,默认返回
undefined
3. Null 类型
- Null 类型只有一个值"
null
"。 - null 值表示一个空对象指针,所以使用
typeof
会返回"object
"; -
undefined
值是派生于null
的,因此会有null == undefined //true
。 - null转为数字时,自动变成0。
- null表示空值,即该处的值现在为空。调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空。
- 无论在何种情况下都没必要把一个变量显式地设置为
undefined
,但是只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null
值。
4. Boolean 类型
- 转换规则是除了下面六个值被转为
false
,其他值都视为true
,包括空数组([])和空对象({})。- undefined
- null
- false
- 0
- NaN
- ""或''(空字符串)
类型转换
Boolean(x)
!!x
5. Number 类型
浮点数值
- 所有数字都是以 64 位浮点数形式储存,即使整数也是如此,JavaScript 语言的底层根本没有整数。
- 如果浮点数本身是一个整数(如:1.0),那么该值会转换为整数(转成32位)(1等价于1.0)。
- 浮点数计算会产生舍入误差问题。(如:0.1 + 0.2 === 0.3不成立)
数值范围
- 如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,返回
Infinity
。 - 如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),那么就会发生为“负向溢出”,返回0.
- 判断一个值是否有穷,使用
isFinite()
函数。
NaN
- 该数值表示一个本来要返回数值的操作数未返回数值的情况。
- 0 / 0 结果为
NaN
。 - NaN 与任何数值不相等,包括 NaN。
- 数组的
indexOf
方法内部使用的是严格相等运算符,所以该方法对NaN不成立。[NaN].indexOf(NaN)
- 使用
isNaN("blue")
函数,任何不能被转换为数值的值都返回 true,但是,对于空数组和只有一个数值成员的数组,isNaN 返回 false。 - 0 除以 0 也会得到 NaN。
数值转换
-
Number()
可以用于任何数据类型,parseInt()
和parseFloat()
是专门把字符串转换为数值。 -
parseInt()
:
- 它的第二个参数:确定转换时的进制。
- 如果
parseInt()
的参数不是字符串,则会先转为字符串再转换。 - 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回 NaN。
- 对于那些会自动转为科学计数法的数字,
parseInt()
会将科学计数法的表示方法视为字符串,因此导致一些奇怪的结果。parseInt(1000000000000000000000.5) // 1 // 等同于 parseInt('1e+21') // 1 parseInt(0.0000008) // 8 // 等同于 parseInt('8e-7') // 8
parseFloat()
- 只能解析十进制。
-
parseFloat()
会将空字符串转为 NaN。 -
parseFloat()
方法会自动过滤字符串前导的空格。 - 如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回 NaN。
- x - 0
- x
数值的进制
- 十进制:没有前导
0
的数值。 - 八进制:有前缀
0o
或00
的数值,或者有前导0
、且只用到 0-7 的八个阿拉伯数字的数值,如果前导 0 后面有数字 8 和 9,则该数值被视为十进制。 - 十六进制:有前缀
0x
或0X
的数值。 - 二进制:有前缀
0b
或0B
的数值。
6. String 类型
- Boolean、Number、String 都有
toString()
方法,但 null 和 undefined 没有。 - 如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠。反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错。(这种方式可读性差,建议用连接运算符+)
var longString = 'Long \ long \ long \ string'; longString // "Long long long string"
反斜杠转义三种特殊用法
-
\HHH
:反斜杠后面紧跟三个八进制数(000到377),代表一个字符。HHH对应该字符的 Unicode 码点,比如\251表示版权符号。显然,这种方法只能输出256种字符。 -
\xHH
:\x后面紧跟两个十六进制数(00到FF),代表一个字符。HH对应该字符的 Unicode 码点,比如\xA9表示版权符号。这种方法也只能输出256种字符。 -
\uXXXX
:\u后面紧跟四个十六进制数(0000到FFFF),代表一个字符。XXXX对应该字符的 Unicode 码点,比如\u00A9表示版权符号。
字符串与数组
- 字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)。
var s = 'hello'; s[0] // "h" s[4] // "o" // 直接对字符串使用方括号运算符 'hello'[1] // "e"
- 如果方括号中的数字超过字符串的长度,或者方括号中根本不是数字,则返回
undefined
。 - 字符串内部的单个字符无法改变和增删,这些操作会默默地失败。
-
字符集
- JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符。
var f\u006F\u006F = 'abc'; foo // "abc"
- 每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。但是,UTF-16 有两种长度:对于码点在U+0000到U+FFFF之间的字符,长度为16位(即2个字节);对于码点在U+10000到U+10FFFF之间的字符,长度为32位(即4个字节),而且前两个字节在0xD800到0xDBFF之间,后两个字节在0xDC00到0xDFFF之间。举例来说,码点U+1D306对应的字符为𝌆,它写成 UTF-16 就是0xD834 0xDF06。
- JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符。
Base64 转码
- 有时,文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。
- 所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+和/这64个字符组成的可打印字符。
-
btoa()
:任意值转为 Base64 编码 -
atob()
:Base64 编码转为原来的值 - 要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。
function b64Encode(str) { return btoa(encodeURIComponent(str)); } function b64Decode(str) { return decodeURIComponent(atob(str)); } b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE" b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
任意类型转字符串
-
String()
String(1) //"1" String(true) //"true" String(null) //"null" String(undefined) //"undefined" String({}) //"[object Object]"
-
toString()
(1).toString() //"1" true.toString() //"true" null.toString() //报错 undefined.toString() //报错 {}.toString() //报错 ({}).toString() //"[object Object]"
-
x + ''
1 + '' //"1" true + '' //"true" null + '' //"null" undefined + '' //"undefined " {} + '' //0 var o = {}; o + ''; //"[object Object]"
7. Object 类型
- 如果键名是数值,会被自动转为字符串。
var obj = { 1: 'a', 3.2: 'b', 1e2: true, 1e-2: true, .234: true, 0xFF: true }; obj // Object { // 1: "a", // 3.2: "b", // 100: true, // 0.01: true, // 0.234: true, // 255: true // } obj['100'] // true
- 如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。
-
{ foo: 123 }
这是表达式还是语句?:JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象。({ foo: 123 }) // 正确 ({ console.log(123) }) // 报错
-
Object.keys(object)
:查看一个对象本身的所有属性。 -
delete
:用于删除对象的属性,删除成功后返回true。删除一个不存在的属性,delete不报错,而且返回true。无法删除继承的属性。 -
in
:用于检查对象是否包含某个属性,但它不能识别哪些属性是对象自身的,哪些属性是继承的。 -
hasOwnProperty("name")
: 用于检查属性是否在对象中,不包括继承属性。 -
isPrototypeOf(object)
: 用于检查给定对象是否为当前对象的原型。 -
propertyIsEnumerable("name")
: 用于检查属性是否能用 for-in 枚举。