在javaScript中任何不是字符串、数值、符号、布尔,null,undefined的值都是对象
1.创建对象
1.1通过字面量
let empty = {}
let user = { name: 'admin', age: 18 }
// 值也可以引用其它对象
let order = { id: 123456789, name: 'orderName', userName: user.name }
console.log(empty); // {}
console.log(user); // {name: "admin", age: 18}
console.log(order); // {id: 123456789, name: "orderName", userName: "admin"}
1.2new关键字:
创建和初始化对象,后面必须跟着一个函数,这种函数称为构造函数
let object = new Object(); // 创建空对象和{}相同
let arrayObject = new Array() // 创建空数组和[]相同
1.3Object.create()函数
let user2 = Object.create({ name: 'user', age: 18 })
console.log(user2.name); // user
let user3 = Object.create(null) //这样会创建一个没有原型对象,所以连基本toString对象都没有
console.log(user3); // {}
原型链
:几乎每个javascript对象都有另一个与之关联的对象,这另一个对象称为原型(prototype
),javascript对象从这个对象继承属性。
- 通过字面量创建的对象都有同一个原型对象,通过
Object.prototype
引用这个对象 - 而new关键字和构造函数创建的对象使用[
构造函数.prototype
]属性的值作为原型,比如new Array()就是以Array.prototype为原型。
几乎所有的对象都有原型对象,但是只有少数对象有prototype
属性,正是这些少数有prototype
属性的对象为其它对象定义了原型,Object.prototype
是为数不多的没有原型的对象,因为它不继承任何属性,多数内置构造函数都继承于Object.prototype
比如Date.prototype
,这些继承连接起来的称为原型链
2.查询和设置对象属性
2.1查询属性
可以通过.属性名称
和[属性名称]
获取对象属性,查询对象不存在的属性将返回undefined
,但是查询不存在的对象的属性则会报错
let student = { name: 'admin', age: 18 }
console.log('name = ' + student.name + ' age = ' +student['age']) // name = admin age = 18
通过in
关键字还可以测试对象中是否存在属性,或者使用hasOwnProperty()
和propertyIsEnumerable()
方法
le o = { x: 1 };
'x' in o; // true
'y' in o; // false
let w = { x: 1 };
console.log('x' in w); // true
'x' in w;
console.log(w.hasOwnProperty('x')); // true
console.log(w.propertyIsEnumerable('x')); // true
当然也可以使用对象名 != undefined
的语法来判断是否存在属性,但是in
可以检测出存在但是赋值给undefined的属性
let test = { x: 1 };
test.x = undefined;
console.log('x' in test); // true
console.log(test.x !== undefined); // false
2.2设置属性
可以通过.属性名称
和[属性名称]
修改或者添加对象属性
let student = { name: 'admin', age: 18 }
student.school = '北清大学'
student['specialty'] = 'software engineering'
// {name: "admin", age: 18, school: "北清大学", specialty: "software engineering"}
console.log(student)
2.3继承
如果我们要查询一个对象的属性,当前对象没有查到,那么将会从改对象的原型链一层层往上查询
查询属性会用到原型链,但是设置或者修改属性只会在当前对象进行
案例分析:
let a = {}; // a从Object.prototype继承对象方法
a.x = 1; // a增加了x属性
let b = Object.create(a); // b继承了a对象方法同时也间接继承了Object.prototype继承对象方法
b.y = 2; // b增加了y属性
let c = b.toString(); // toString()继承于Object.prototype
let d = a.x + b.y; // 等价于 let d = b.x + b.y;
console.log(c); // [object Object]
console.log(d); // 3
2.4删除属性
使用delete
可以删除对象属性,但是不会删除继承的属性,删除成功或者删除不存在的属性都会返回true,
但是delete
不会删除configuration
特性为false的属性,比如Object.prototype
语法:
delete book.author;
delete book['author'];
2.5枚举属性
使用常规javascript创建的属性都是枚举属性
遍历所有属性
let test2 = { x: 1, y: 2, z: 3 };
for(p in test2){
console.log(p); // x y z
}
也可以通过获取对象的所有属性的数组(如Object.keys()),在遍历该数组
let test2 = { x: 1, y: 2, z: 3 };
let arrTest2 = Object.keys(test2);
for(p in arrTest2){
console.log(test2[arrTest2[p]]); // x y z
}
3.扩展对象
将一个对象的所有属性赋值赋值到另一个对象上,使用Object.assign方法,局限性:会覆盖目标对象的属性
let test2 = { x: 1, y: 2, z: 3 };
let test3 = { x: 5 }; // x 会被覆盖
Object.assign(test3, test2)
let arrTest2 = Object.keys(test3);
for(p in arrTest2){
console.log(test2[arrTest2[p]]); // 1 2 3
}
4.序列化对象
把对象的状态转成字符串,再恢复成对象的过程
let test4 = { x: 1, y: 2, z: { z: 5} };
let s = JSON.stringify(test4)
console.log(typeof s); // string
// 转成对象
let obj = JSON.parse(s)
console.log(typeof obj); // object
5.对象方法
5.1toString()
当需要把一个对象转成字符串时会常调用,如下
let test5 = { x: 1, y: 2, z: { z: 5} };
console.log(test5.toString()); // [object Object]
但是返回内容有限,往往需要重写该方法
let test5 = { x: 1, y: 2, z: { z: 5}, toString: function(){
return "x=" + this.x + " y=" + this.y + " z=" + this.z.z
}};
console.log(test5.toString()); // x=1 y=2 z=5
5.2toLocaleString()
返回对象的本地化字符表示,Object定义的toLocaleString()只是单纯调用toString(),但是Data和Number类定义了自己的oLocaleString()方法,尝试根据本地管例格式化数字和日期
5.3valueOf()
和toString()相似,Date类会将日期转为数值用于比较