JS 里的数据类型

2018-12-13  本文已影响0人  七月凛冬

JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。

通常,数值、字符串、布尔值这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。至于undefined和null,一般将它们看成两个特殊值。
对象可以分成三类:


关于typeof运算符
typeof运算符可以返回一个值的数据类型。
数值、字符串、布尔值分别返回numberstringboolean

typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"

函数返回function。(函数属于对象的一种,理论应该返回object,但是js里是返回function,算是bug)

undefined返回undefined

利用这一点,typeof可以用来检查一个没有声明的变量,而不报错。

a
// ReferenceError: v is not defined

typeof a
// "undefined"

上面代码中,变量a没有用var命令声明,直接使用就会报错。但是,放在typeof后面,就不报错了,而是返回undefined

对象返回object

typeof window // "object"
typeof {} // "object"
typeof [] // "object"

null返回object。(实际上null的类型就是null,返回object也算是bug)

typeof null // "object"

null返回的类型是object,这是由于历史原因造成的。1995年的 JavaScript 语言第一版,只设计了五种数据类型(对象、整数、浮点数、字符串和布尔值),没考虑null,只把它当作object的一种特殊值。后来null独立出来,作为一种单独的数据类型,为了兼容以前的代码,typeof null返回object就没法改变了。


一、数值(number)

  1. 关于数值的进制
    使用字面量(literal)直接表示一个数值时,JavaScript 对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制。

默认情况下,JavaScript 内部会自动将八进制、十六进制、二进制转为十进制。
如果八进制、十六进制、二进制的数值里面,出现不属于该进制的数字,就会报错。

  1. 关于NaN
    NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。
2 - 'w'  //报错

上面代码运行时,会自动将字符串x转为数值,但是由于x不是数值,所以最后得到结果为NaN,表示它是“非数字”(NaN)。
NaN不是独立的数据类型,而是一个特殊数值,它的数据类型依然属于Number
NaN不等于任何值,包括它本身。

NaN === NaN //  false

二、字符串(string)

  1. 定义
    字符串就是零个或多个排在一起的字符,放在单引号或双引号之中。
'bbb'
"aaa"

单引号字符串的内部,可以使用双引号。双引号字符串的内部,可以使用单引号。

"'key' = value"
'hello "world" yeah'

如果要在单引号字符串的内部,使用单引号,就必须在内部的单引号前面加上反斜杠,用来转义。双引号字符串内部使用双引号,也是如此。

'go go \'go\''    //"go go 'go'"

注意,转义符\与后面的任何字符数字都只算一个length,转义符也可以转转义本身。\\
空字符串''和空格字符串' '是不一样的,前者length为0,后者为1。

如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠。(不建议这种方法)

var a ='a\
c\
e';

输出的时候还是单行,效果与写在同一行完全一样。注意,反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错。

连接运算符(+)可以连接多个单行字符串,将长字符串拆成多行书写,输出的时候也是单行。(分成多行建议这种方法)

var b ='a'
+'c'
+'f';

三、布尔值(Boolean)

布尔值代表“真”和“假”两个状态。“真”用关键字true表示,“假”用关键字false表示。布尔值只有这两个值。

相与运算符&&
a&&b必须要a和b同时为true或者false,结果才会是true false
或运算符|| 只要a或者b有一个是true时,结果就是true,只有当ab同时为false时,结果才是false


四、null 和 undefined

null与undefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,都表示什么都没有。
区别:


五、对象(object)

  1. 生成方法
    对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。
var obj = {
  foo: 'Hello',
  bar: 'World'
};

上面代码中,大括号就定义了一个对象,它被赋值给变量obj,所以变量obj就指向一个对象。该对象内部包含两个键值对(又称为两个“成员”),第一个键值对是foo: 'Hello',其中foo是“键名”(成员的名称),字符串Hello是“键值”(成员的值)。键名与键值之间用冒号分隔。第二个键值对是bar: 'World'bar是键名,World是键值。两个键值对之间用逗号分隔。

  1. 键名
    对象的所有键名都是字符串,所以加不加引号都可以。如果键名是数值,会被自动转为字符串。
    如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。
    对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

  2. 属性的读取
    读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。

var obj = {
  p: 'Hello'
};
obj.p // "Hello"
obj['p'] // "Hello"

上面代码分别采用点运算符和方括号运算符,读取属性p
注意,如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。

var f = 'b';

var obj = {
  f: 1,
  b: 2
};

obj.f  // 1
obj[f]  // 2

上面代码中,引用对象objf属性时,如果使用点运算符,f就是字符串;如果使用方括号运算符,但是不使用引号,那么f就是一个变量,指向字符串b

方括号运算符内部还可以使用表达式。数字键可以不加引号,因为会自动转成字符串。

obj['hello' + ' world']
obj[3 + 3]

注意,数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。

var obj = {
  123: 'hello world'
};

obj.123 // 报错
obj[123] // "hello world"

上面代码的第一个表达式,对数值键名123使用点运算符,结果报错。第二个表达式使用方括号运算符,结果就是正确的。

  1. 属性的查看
    查看一个对象本身的所有属性,可以使用Object.keys方法。
var obj = {
  key1: 1,
  key2: 2
};

Object.keys(obj);
// ['key1', 'key2']
  1. 属性的删除:delete 命令
    delete命令用于删除对象的属性,删除成功后返回true
var obj = { p: 1 };
Object.keys(obj) // ["p"]

delete obj.p // true
obj.p // undefined
Object.keys(obj) // []

上面代码中,delete命令删除对象objp属性。删除后,再读取p属性就会返回undefined,而且Object.keys方法的返回值也不再包括该属性。
注意,删除一个不存在的属性,delete不报错,而且返回true。因此,不能根据delete命令的结果,认定某个属性是存在的。
只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

  1. 属性是否存在:in 运算符
    in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false
var obj = { a: 1 };
'a' in obj // true
  1. 属性的遍历:for...in 循环
    for...in循环用来遍历一个对象的全部属性。
var obj = {a: 1, b: 2};

for (var key in obj) {
  console.log(key);
  console.log(obj[key]);
}
//  a
//  1
//  b
//  2

注意,遍历出的顺序并不一定是按照对象内部的顺序排列的。它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。

上一篇下一篇

猜你喜欢

热点阅读