对象 object,七种数据类型中唯一的复杂类型
定义
- 无序的数据集合
- 键值对的集合
写法
let obj = {'name'='mike','age'=18}let obj = new Object({'name':'mike',age:19}) //正规写法console.log({'name':'mike','age':18}) //打印一个没有名字的对象,匿名对象- 键名是字符串,不是标识符,可以包含任意字符
- 引号可以省略,省略之后就只能写标识符
//不写引号不能包含空格和中文
let obj = {
}
- 属性名只能是字符串,即使没有加引号也是字符串
let obj={2:198}
Object.keys(obj) //该api获得对象的所有属性名
//得到的是一个数组['2']
属性名
每个key都是对象的属性名(property)
属性值
每个value都是对象的属性值(property)
变量做属性名
let phone = '13232232323'
let obj = {phone:'110'} //这样写,属性名为字符串'phone'
let obj = {[phone]:'110'}
//用中括号将变量名括起来,会当做变量求职,属性名为phone的值
//值为{'13232232323':'110'}
//如果[phone]不存在则报错
//[]的值如果不是字符串,则会变为字符串
对象的隐藏属性
- JavaScript中每一个对象都有一个隐藏属性
- 这个隐藏属性储存着其 共有属性组成的对象 的地址
- 这个 共有属性组成的对象 叫做原型
- 也就是说,隐藏属性储存着原型的地址
let obj = {}
obj.toString()
//没有报错,因为obj的隐藏属性的对象上有toString方法
删除对象属性
let obj = {
name:mike",
age:18
}
obj.name = undefined //删除属性值,属性名仍存在
delete obj.age //删除属性值及属性名
//等价于 delete obj['age']
in操作符检查属性名是否在目标对象中,但不会区分自身属性还是共有属性
let obj = {
age = 18
}
let temp = 'age'
'age' in obj //返回true
temp in obj //返回true
检查属性名存在,但是值为undefined
let obj = {
age:undefined
}
let p = 'age'
p in li && li[p] === undefined
//返回true
不能通过obj.xxx === undefined 来判断xxx是否为obj的属性
let obj = {
age:undefined
}
obj.age === undefined //有属性名但值为undefined,返回true,此方法不严谨
查看对象的属性(读)
查看自身所有属性
var obj = {
name : 'haha',
age : 18
}
Object.keys(obj) //查看对象的所有属性名,返回一个数组
// ["name", "age"]
Object.values(obj) //查看对象的所有属性值,返回一个数组
["haha", 18]
Object.entries(obj) //查看所有属性名和属性值,返回两个数组
查看自身属性+共有隐藏属性
var obj = {
name : 'haha',
age : 18
}
console.dir(obj) //控制台输出
obj.__proto__ //返回对象的所有隐藏属性
判断一个属性是自身属性还是共有属性
var obj = {
name : 'haha',
age : 18
}
obj.hasOwnProperty('name') //返回true
obj.hasOwnProperty('toString') //返回false
原型
每个对象都有原型
- 原型里存着对象的共有属性
- 比如obj的原型就是一个对象
- obj.proto 存着这个对象的地址
- 这个对象里有 toSTring/construtor/valueOf 等属性
对象的原型也是对象
- 所以对象的原型也有原型
- obj={} 的原型既为所有对象的原型
- 这个原型包含所有对象的共有属性,是对象的根
- 这个原型也有原型,是null
两种方法查看属性
- 中括号语法:obj['key']
- 点语法:obj.key
- obj[key]的值一般不为key,因为key是变量
修改或者增加一个属性
直接赋值
let obj = {
name : 'mike'
}
obj.age = 18 //如果不存在,则会直接增加
obj.name = 'jack' //如果存在,则会直接修改
//obj['name'] = 'jack' //等价于点语法
批量赋值
let obj = {}
Object.assign(obj,{age:18,name:'kimi'})
//第一个参数为要赋值的对象,第二个参数为{}包起来的键值对
修改原型注意事项
无法通过自身修改或增加共有属性
let obj1 = {}
let obj2 = {}
obj1.toString = 'fn' //只会修改自身属性,不会修改原型的属性
obj2.toString === 'fn' //返回false,obj2的toString方法还是原型上的方法
强行修改原型对象属性
let obj1 = {}
let obj2 = {}
obj1.__proto__.toString = 1
obj2.toString //值为1,因为原型被修改了
//不推荐使用__proto__
//使用构造函数的prototype修改原型
Object.prototype.toString = 1
obj1.__proto__ = null
//obj1没有隐藏属性
修改原型链
let action = {
walk : function(){
console.log(walk)
}
}
let cat = Object.create(action) //以action为原型创建cat
cat.__proto__ === action //返回ture