对象有两种定义方式
声明(文字)形式
var obj = {
key: value
//..
};
构造形式
var obj = new Object();
obj.key = value;
//..
两种定义方式生成的对象是一样的,唯一的区别在于声明方式一次性能添加多个键值对
类型
JavaScript有六种主要类型,包括五种简单基本类型(string,number,boolean,null,undefined)和对象(object)
(null不是对象类型,但是typeof null会返回字符串"object",其实是因为JavaScript是根据二级制前三位是不是都是0来判断是不是object类型的,而null的二级制表示是全0,于是就被当做object类型了)
除此之外还有很多特殊的对象子类型(就是可调用的对象,也叫复杂基本类型),比如说函数(function),又比如说数组(array)
数组也是对象中的一种类型,但是又具备一些额外的行为
因此内容的组织方式比一般的对象要更复杂一些,比如数组的下标是数字,而对象的属性名一定是字符串
还有包括String,Number,Boolean,Object,Function,Array,Date,RegExp,Error等
乍一看好像名字都跟普通基本类型一样,但实际上它们只是一些拿来当做构造函数(new操作符)的内置函数,从而构造一个对应子类型的新对象
var str = "I am a string";
console.log(typeof str, str instanceof String); //string,false 表示str是string类型的,并不是由String构造函数创建
var strObj = new String("I am a string");
console.log(typeof strObj, strObj instanceof String); //object,true 表示str是object类型的,由String构造函数创建
原始值"I am a string"不是一个对象,只是一个字面量,不可变,也无法进行操作,但是必要时JavaScript会自动把字面量转换为一个String对象,以此来访问属性和方法.
而null和undefined没有对应的构造形式,只有文字形式
相反,Data只有构造,没有文字形式
而对于Object,Array,Function和RegExp(正则表达式)来说,不管是文字形式还是构造形式,他们都是一个对象,而不是一个字面量
内容
对象的内容是由属性组成的
也就是一些存储在特定命名位置的值(任意类型)
但实际上这些值并不存储在对象内部,存储的只是对这些值的引用,可以理解为指针,指向真正的存储位置
访问对象中属性,也就是key位置上的value有两种方法
.操作符(点操作符,属性访问)和[]操作符(键访问)
区别在于[]操作符可以访问一些命名不是那么规范的属性,比如123-a无法用 . 操作符访问,却可以用[] 操作符访问
var obj = {
"123-a": "123"
}
console.log(obj["123-a"]);//123
在对象中属性名永远都是字符串
如果使用string(字面量)以外的其他值作为属性名,那它也会首先被转换为一个字符串,包括数字也是一样(而数组的下标确实是数字)
同时,由于[".."]中使用字符串来访问属性,所以可以通过自己创建一个字符串来进行访问,比如 var idx="123-a"; obj[idx];
同时也可以使用obj[idx1+idx2]这种形式来访问,但是无法通过文字形式来声明对象
在ES6中增加了可计算属性名,这意味着在文字形式来声明对象中也可以用[]来包裹一个表达式来当做属性名了
var idx = "a";
var obj = {
[idx + "bc"]: 123
}
console.log(obj["abc"]); //123
数组
数组也支持[]的访问形式,不过数组期望的是数值下标,也就是说值存储的位置(索引)是非负整数
但是数组也是对象,所以虽然下标都是整数但是依然可以用字符串来给数组添加属性
var arr = [1, 2, 3];
arr.name = "arr";
console.log(arr.length, arr.name); //3,"arr"
可以看到就算添加了属性,但是length并没有发生改变
数组跟普通对象还有一个区别就是
普通对象[]中就算是一个数字,也会首先被转换为字符串
而数组对象如果[]中是个看起来像数字的字符串,那么会把它变成一个数值下标
var arr = [1, 2, 3];
console.log(arr['2']); //3