值(Values)
JavaScript有所有我们期待的编程语言值类型:布尔,数字,字符串,数组等。JavaScript中的所有值都有属性。每个属性有一个键(或名字)和一个值。参考记录的域(fields of record)。你可以使用点(.
)操作符读取属性:
value.propKey
举个例子:字符串“abc
”有属性lenght(长度)。
> var str = 'abc';
> str.length
3
上面的代码也可以写成下面这样:
> 'abc'.length
3
点操作符也可以用来给属性赋值:
> var obj = {}; // 空对象
> obj.foo = 123; // 创建属性“foo”,设置它为123
123
> obj.foo
123
你也可以通过它(.)调用方法:
> 'hello'.toUpperCase()
'HELLO'
上面,我们在值“hello
”上面调用方法 toUpperCase()
。
原始类型值和对象(Primitive values versus objects)
JavaScript定义了不同值之间的区别:
- 原始值包括:boolean,number,string,null和undefined,
- 所有其他的值都是对象。实际上对象被定义为——所有不为原始值的值。
两者之间的主要区别在于他们是如何被比较的:每一个对象有一个独一无二的标志,并且仅和自己相等:
> var obj1 = {}; // 一个空对象
> var obj2 = {}; // 另一个空对象
> obj1 === obj2
false
> obj1 === obj1
true
相反,所有原始值只要编码值相同就被认为是相同的:
> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true
接下来的两节会介绍原始值和对象的更多细节。
原始类型值(Primitive values)
下面全是原始类型值(简称:原始值
):
- 布尔类型:
true
,false
- 数字类型:
1736
,1.351
- 字符串类型: ‘
abc
’,”abc
” - 两个“无值(non-values)”:
undefined
,null
原始值的特征:
- 值做比较时:“
内容
”做比较。> 3 === 3 true > 'abc' === 'abc' true
- 无法更改:值的属性无法更改,无法添加和移除属性。
> var str = 'abc'; > str.foo = 3; // try to create property `foo` ⇒ no effect > str.foo // unknown property undefined
(获取未知属性总返回undefined
)
- 原始值的集合是固定的(fixed set of values):你不能自定义原始值。
对象(Objects)
所有非原始值(non-primitive)的值都是对象。最常见的几种对象类型是:
- 简单对象(类型是Object)能通过对象字面量创建:
{ firstName: ‘Jane’, lastName: ‘Doe’ }
上面的对象有两个属性:
firstName
属性的值是“Jane
”,lastName
属性的值是“Doe
”。
- 数组(类型是 Array)能通过数组字面量创建:
[ ‘apple’, ‘banana’, ‘cherry’ ]
上面的数组有三个元素,可以通过数字索引访问。例如“apple
”的索引是0
.
- 正则表达式对象(类型是 RegExp)能通过正则表达式字面量创建。
/^a+b+$/
对象的特征:
-
比较的是引用:比较的是标识符,每个值有自己的标识符。
> {} === {} // 两个不同的空对象 false > var obj1 = {}; > var obj2 = obj1; > obj1 === obj2 true
- 默认可以更改。
> var obj = {}; > obj.foo = 123; > obj.foo 123
undefined 和 null(undefined and null)
多少有些不必要,JavaScript有两个“无值(non-values)
”:undefined
和 null
。
undefined的意思是“没有值(no value)
”。未初始化的变量是undefined
:
> var foo;
> foo
undefined
读取不存在的属性时,将返回undefined
:
> var obj = {}; // 空对象
> obj.foo
undefined
缺省的参数也是undefined
:
> function f(x) { return x }
> f()
undefined
null
的意思是“没有对象(no object)
”。它被用来表示对象的无值(参数,链上的对象等)。
通常情况下你应该把undefined
和null
看成是等价的,如果他们代表相同意义的无值的话。检查他们的一种方式是通过严格比较:
if (x === undefined || x === null) {
...
}
另一种在实际中使用的方法是认为undefined
和 null
都是false:
if (!x) {
...
}
警告:false
,0
,NaN
和 “” 都被当作false。
包装类型(Wrapper types)
对象类型的实例Foo(包括内建类型,例如Array和其他自定义类型)从对象Foo.prototype
上获取方法。你可以通过读取这个方法的方式(不是调用)验证这点:
> [].push === Array.prototype.push
true
相反,原始类型是没有类型的,所以每个原始类型有一个关联类型,称之为包装类型:
- 布尔值的包装类型是 Boolean。布尔值从
Boolean.prototype
上获取方法:> true.toString === Boolean.prototype.toString true
注意包装类型名字的首字母是大写的B。如果在JavaScript中布尔值的类型可以访问,那么它可能会被转换为布尔对象。
- 数字值的包装类型是Number。
- 字符串值的包装类型是String。
包装类型也有实例(他们的实例是对象),但不常用。相反,包装类型有其他用处:如果你将他们作为函数调用,他们可以将值转换为原始类型。
> Number('123')
123
> String(true)
'true'
通过typeof 和 instanceof 将值分类(Categorizing values via typeof and instanceof)
有两个操作符可以用来将值分类:typeof 主要用于原始值,instanceof 主要用于对象。 typeof 使用方法如下:
typeof «value»
typeof
返回描述 value
“类型
”的一个字符串。例如:
> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // 空对象字面量
'object'
> typeof [] // 空数组字面量
'object'
下面列出了typeof操作的所有结果:
操作数 | 结果 |
---|---|
undefined | undefined |
null | object |
Boolean value | boolean |
Number value | number |
String value | string |
Function | function |
All other values | object |
有两个结果和我们上面说的的原始值与对象是矛盾的:
- 函数的类型是“
function
”而不是“object
”。鉴于函数(类型 为“function
”)是对象(类型是对象)的子类型,这不是一个错误。 null
的类型是“object
”。这是一个bug
,但从没被修复,因为修复后会破坏现有的代码。
instanceof使用方法如下:
«value» instanceof «Constr»
如果 value 是一个对象,并且value 是由构造函数Constr创建的(参考:类)。例如:
> var b = new Bar(); // 通过构造函数Bar创建对象
> b instanceof Bar
true
> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object // 数字是对象的子类型
true
更多建议: