2019-08-03对象
先回顾一下JS中的数据类型:
- String
- Boolean
- Number
- Null
- Undefined
- Object
前五种是,
在JS中,数据值只要不是基本数据类型,那么就可以认为是Object。
所以,JS里的Object涵盖很广,包括了数组,函数function
引入Object是为了弥补基本数据类型的不足,表现在以下:
1.基本数据类型都是单一的值,值与值之间没有联系
比如,我想表示一个人,这个人有很多信息,比如姓名,年龄,性别。
用基本数据类型创建出来的数据都是独立的,不能形成一个整体。
var name = "小明";
var age = 16;
var gender = "女";
而用Object表示的话可以表示成一个整体
对象属于一种复合数据类型,在对象中可以保存不同的数据类型的属性。
var people = {
name : "小明",
age: 16,
gender: "女"
};
对象的分类
- 内建对象:
由ES标准中定义的对象,在任何的ES的实现中都可以使用。
比如:Math,String,Boolean,Number,Object,Function…… - 宿主对象:
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
比如:BOM(浏览器对象模型),DOM(文档对象模型) - 自定义对象:
由开发人员自己创建的对象
对象的基本操作
基本操作包括对象的创建,添加属性,删除属性,转换为其他数据类型,对象的销毁等等。
创建对象
var people1 = new Object();
var people2 = {};
new运算符,会去调用对象的构造函数constructor,从而创建一个对象。
对象的属性
对象里面保存值的方式是属性名:属性值
通过new关键字创建出来的对象是空对象,我们可以给对象添加或者删除属性来满足日常开发中的需求。
- 访问属性
语法1:对象.属性名
语法2:对象["属性名"]
使用中括号访问对象属性的方式更加灵活,我们可以在中括号里边传入一个变量,则会根据变量动态的查找对应的对象的属性。(变量可以是任何的基本数据类型,会转换为String类型) - 添加属性
语法1:对象.属性名 = 属性值
语法2:对象["属性名"] = 属性值 - 修改属性
语法1:对象.属性名 = 属性值
语法2:对象["属性名"] = 属性值 - 删除属性
语法1:delete 对象.属性名
语法2:delete 对象["属性名"]
如果读取对象中没有的属性,返回Undefined;区别于读取未声明的变量,这会报错。
var people1 = new Object();
var people2 = {};
people1.name = "小明";
people1.age = 16;
people1.gender = "女";
people2.name = "小花"
people2.age = 20;
people2.gender = "女";
people1.name = "晴晴";
delete people2.gender;
console.log(people1);
console.log(people2);
console.log("people1的性别", people1.gender);
console.log("people2的性别", people1["gender"]);
图片.png
注意:.
,[]
,new
运算符是优先级最高的
属性名
不强制要求符合标识符的规范,但尽量别这么去做。
如果采用了特殊的属性名,访问属性则不能再通过.
,需要通过另外一种方式。
属性值
JS对象的属性值可以是任何的数据类型,甚至可以是一个对象。
我们可以使用 in 运算符
检测对象中是否含有某个属性,有返回true,没有返回fasle。
语法:属性名 in 对象
引用数据类型
通俗来说,引用数据类型就是按址访问,而基本数据类型是按值访问。
var a , b;
a = 3;
b = a;
var c , d;
c = {name:"小花", gender:"女"};
d = c;
a++;
c.name = "小华";
d.gender = "男";
console.log(a,b);
console.log("c", c);
console.log("d", d);
a与b不会互相影响,而c与d则会互相影响
造成这样的原因与JS如何保存数据有关。
JS里面有栈内存与堆内存之分:
- 所有的变量都是保存在栈内存中的
-
基本数据类型直接在栈内存中存储
值与值之间独立存在 -
引用数据类型保存到堆内存,每创建一个新的对象,就在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址
图片.png
来几个例子加深对引用数据类型的理解
我们来看一种情况:下面代码中people1是否也会变成null,通过结果发现并没有变为null
var people1 = {name: "Jan"};
var people2 = people1;
people2 = null;
console.log("people1",people1);
console.log("people2",people2);
图片.png
原因就是,我们只是改变了变量的值,让变量失去了对对象的引用,代码并没有改变对象的值。
图片.png
var obj3 = new Object();
var obj4 = new Object();
obj3.name = "孙悟空";
obj4.name = "孙悟空";
console.log(obj3 == obj4);
console.log(obj3.name == obj4.name)
var obj5 = obj3;
obj5.name = "沙和尚"
console.log(obj5 == obj3);
console.log(obj5,obj3);
结果
obj3和obj4不相等的原因:new运算符会开辟一个新的内存空间,将新的内存地址赋给变量,故而变量obj3与obj4不相等
obj3和obj4不相等的原因:new运算符会开辟一个新的内存空间,将新的内存地址赋给变量obj4,故而变量obj3与obj4不相等
obj3和obj5相等的原因:我们通过赋值运算符(=)将obj3的值(即是对应对象的地址)赋值给了obj5,故相等。
注意,变量之间的比较不是按址比较,就是按值比较,只不过,对于obj3,obj4,obj5而言,他们的值代表了地址而已。
obj3的name属性与obj4的name属性是相等的,因为按值比较,他们的值就是相等的。
对象字面量
我们上面介绍了创建对象可以有两种方式,一种是通过new运算符,一种是通过{}。
通过对象字面量创建对象时可以直接设置对象的属性。
对象字面量里面的属性名可以加引号,也可以不加引号;推荐不加。但是如果属性名比较特殊,则一定要加上引号。