JS基础(六)对象(上)
欢迎阅读,本篇主要介绍JS中的对象。
前言
我们工作中常听到用的对象,但你真的了解它吗?希望本篇对你学习对象有所帮助。
1. 语法
对象可以通过两种形式定义:声明(文字)形式和构造形式。
1 |
|
1 |
|
两种方式声明的对象是一样的。唯一的区别是:在文字声明中你可以添加多个键值对,但在构造形式中你必须逐个添加属性。一般来说,我们使用文字声明创建对象。
2. 类型
类型
在JS中一共有六
种基本类型(语言类型):string number boolean null undefined object
简单基本类型(string、number、boolean、null、undefined)本身并不是对象,null有时会被当作一种对象类型,对null执行typeof null
时会返回字符串“object”
,但这其实只是语言的一个bug:不同的对象在底层都表示为二进制,在JS中二进制前三位都为0的话,会被判定为object类型,null的二进制表示是全0,自然前三位是0,所以执行typeof时会返回“object”。
另外,还有一个错误的说法:“JS中万物皆对象”。实际上,JS中有许多特殊的对象子类型,我们称之为复杂基本类型。
函数就是对象的一个子类型,从技术角度来说就是“可调用的对象”,函数本质上和普通对象一样,只是可调用,所以可以像操作其他对象一样操作函数,比如把函数当作另一个函数的参数。
数组也是对象的一种类型,具备一些额外的行为,数组中内容的组织方式比一般对象要稍微复杂些。内置对象
JS中还有一些对象子类型,通常被称为内置对象
。有些内置对象的名字和简单基础类型一样,不过实际上,他们的关系更复杂1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22String
Number
Boolean
Object
Function
Array
Date
RegExp(正则表达式)
Error
```
在JS中,这些内置对象,实际上是一些内置函数,可以当作构造函数来使用,从而可以构造一个对应子类型的新对象:
``` bash
var StrPrimitive = "I am a string";
typeof StrPrimitive; // "string"
StrPrimitive instanceof String; // false
var strObject = new String("I am a string");
typeof strObject; // "object"
strObject instanceof String; // true
// 检查sub-type对象
Object.prototype.toString.call(strObject); // [object, String]我们可以认为子类型在内部借用了Object中的toString()方法,strObject是由String构造函数创建的一个对象。原始值“I am a string”并不是一个对象,只是一个字面量,并且是一个不可变的值,如果要在这个字面量上执行一些操作,比如获取长度,访问其中某个字符等,那就需要将其转换为String对象。幸好,在必要时语言会自动把字符串字面量转换成一个String对象,并不需要我们显示创建一个对象,能使用文字形式时就不要使用构造形式。
1
2
3var StrPrimitive = "I am a string";
console.log(StrPrimitive.length); // 13
console.log(StrPrimitive.chatAt(3)); // "m"上述例子中,我们可以直接在字符串字面量上访问属性或方法,是因为引擎自动把字面量转换成了String对象。
同样的事情也会发生在数值字面量上:1
42.359.toFixed(2);
引擎会自动把42转换成new Number(42)。对于布尔字面量来说也是如此。
null和undefined没有对应的构造形式,它们只有文字形式。相反,Date只有构造形式,没有文字形式。
对于Object、Array、Function、RegExp来说,无论文字形式还是构造形式,他们都是对象,不是字面量。在某些情况下,相比用文字形式创建对象,构造形式可以提供额外的选项。由于这两种形式都可以创建对象,我们首选更简单的文字形式。建议只在需要那些额外选项时使用构造形式。
Error对象很少在代码中显示创建,一般是在抛出异常时被自动创建,当然也可以用new Error(…)来创建,一般用不到。
3. 内容
对象的内容是由一些存储在特定命名位置的值组成的,我们称之为属性。
需要注意:“内容”并不是指这些值实际上被存储在对象内部,在引擎内部,这些值的存储方式多种多样,一般不会直接存在对象容器内部。存储在对象容器内部的是这些属性的名字,它们就像指针(引用),指向这些值真正存储的位置。
1 |
|
如果要访问myObject
中a
位置上的值,我们需要用.
操作符或者[]
操作符。.a语法通常被称为“属性访问”,[‘a’]语法通常被称为“键访问”。实际上它们访问的是同一个位置,并且会返回相同的值2,所以这两种是可以互换的。我们常见的是“属性访问”。
这两种方式区别:操作符要求属性名满足标识符命名规范,而[“…”]语法可以接受任意UTF-8/Unicode字符串作为属性名,如果你要引用名称为“Super-Fun”的属性,就必须使用[“Super-Fun”]语法访问,因为“Super-Fun”并不是一个有效的标识符属性名。
另外需要注意的是:在对象中属性名永远是字符串,如果你使用string(字面量)以外的其他值作为属性名,它首先也会被转成字符串。即使是数字也不例外,虽然在数组中使用的的确是数字,但是在对象属性名中数字会被转成字符串。
1 |
|
总结
本篇主要学习对象概念内容,下篇学习对象属性方法、数组、对象的复制、遍历等。