对象
var o = { a: 1, b: 2 };
o.a; //o对象下的a属性
o.a = 值; //可以设置属性的值
- 对象的结构形式是键值对结构 键(key) 值(value) 成对
- a 键 1 值
- 键值对中不能出现重复的键
var o = { a: 1, a: 10 }; //错误
- 在对象中键 只能是 string 或者 symbol
var b = false;
o.b = 10; // 这里的o.b 这个b不是变量b而是字符串b
o[b] = 10; // o对象下的键是变量b的值
var a = "c";
var b = "d";
o[a][b] = 100;
var obj = {};
obj.a = 10; //在obj下设置一个a属性,这个属性值是10
obj["a"] = 10; //在obj下设置一个a属性,这个属性值是10
-
点语法对于属性名有要求,必须是类似于变量的命名法则方式,不能直接写数值,非法符号
-
但是对象的键是字符串就可以,允许有各种字符,如果有其他各种字符键时,我们使用
[key]
写入 -
在 key 使用时没有使用""字符串,这时候给入的这个内容系统认为是变量,也就是将变量的值作为 key
var a = 10;
obj[a] = 10;
obj = { 10: 10 };
obj["a"] = {};
obj["a"]["b"] = 2; // {a:{b:2}}
- 任何内容作为 key 时,都会被自动转换为字符串
var a;
var b;
//作为对象的key属性时,都会把这个变量的值转换为字符串
//a变量的值是undefined 转换为字符串时就会变成"undefined"
o[a]=10--->o["undefined"]=10; //变量没有使用"",所以变量是把值作为这里key
o["a"]=20;--->o["a"]=20; //使用""都是字符串
//打印o[b] 先把b转换为字符串 "undefined" 获取对象o中的属性"undefined" 在对象中刚才设置这个"undefined"的值是10,因此获取到了结果是10
遍历
var obj={a:1,b:2,c:3,d:4,e:5};
for in 遍历对象的所有key
for(var key in obj){
}
- 在其他语言中对象的变量是无序的,在 js 中对象的遍历是有规则的
- 所有 key 是数值的优先按照从小到大的顺序,然后再遍历其他的 key,按照创建先后顺序遍历
对象的存储
var o={a:1,b:2};
为啥要做对象。
var a = 1;
var b = 2;
var c = 3;
- 需要在栈中开辟多个空间,无法归类
- 栈就相当于内存,堆就相当于硬盘
- 栈的速度快,堆的速度慢,栈的空间小,堆的空间大
- 想要归类存储,就有对象
{id:10001,name:"mac pro",price:20000,num:1},
{id:10002,name:"iphone 13 pro",price:8000,num:2},
//存在堆中,并且产生一个堆中引用地址
引用地址赋值
//下面就是把引用地址赋值,obj和obj1的结果都是同一个引用地址
var obj = { a: 1, b: 2 };
var obj1 = obj;
obj.a = 2; //修改引用地址所对应的对象
obj = { a: 2, b: 2 }; //修改了引用地址
var obj = { a: 1, b: 2 };
function fn(o) {
o.a = 10;
}
fn(obj);
console.log(obj);
function fn(o) {
o = { a: 10 };
}
fn(obj);
console.log(obj);
复制对象
- 浅复制
var obj = { a: 1, b: 2, c: 3 };
var obj1 = {};
// obj1.a=obj.a;
for (var key in obj) {
obj1[key] = obj[key];
}
obj.a = 10;
console.log(obj1, obj);
- 深复制
function cloneObj(targetObj, sourceObj) {
for (var key in sourceObj) {
if (typeof sourceObj[key] === "object" && sourceObj[key] !== null) {
var o = {};
targetObj[key] = o;
cloneObj(o, sourceObj[key]);
} else {
targetObj[key] = sourceObj[key];
}
}
}
//JSON
JSON.stringify(obj) //将对象转换为JSON字符串
JSON.parse(str) //将JSON字符串转换为对象
//抛出错误
Unexpected token d in JSON at position 22 //JSON字符串有错误
Unexpected token b in JSON at position 0
//这样也可以深复制
var o=JSON.parse(JSON.stringify(obj));
删除属性
var obj = { a: 1, b: 2 };
delete obj.a;
对象的删除
- null 切断引用关系,清除引用列表对应的内容
var obj = { a: 1, b: 2 };
var obj1 = obj;
obj = null;
//对象{a:1,b:2} 的引用变量只有obj1,如果想要彻底清除这个对象
obj1 = null;
-
因为 null 主要的目的是针对引用类型来完成切断引用关系的,所以主要对于引用类型来使用
-
原变量类型时引用类型也就是 object 类型,现在切断了引用关系,变量的类型不改变,仍然是 object
-
内存泄漏
- 不断产生新的孤儿对象,但是没有清除其引用关系,这样会造成堆中引用数据的不断增加,然后占用了大量的堆中空间,造成新的数据减少了运行空间,而速度变慢,这就是内存泄漏
-
孤儿对象
- 对象仍然存在在堆中,但是其引用地址指向某个变量,变量却指向其他的对象
-
垃圾回收
- 当内存上升到一定值,JavaScript 虚拟机就会自动产生一次清除,这个清除会将所有没有引用地址的对象清除掉,以释放堆栈中的空间