JavaScript对象

JavaScript对象

JavaScript对象是七种数据类型中唯一一种复杂类型。

  • 是无序的数据集合
  • 是键值对的集合

声明对象的写法

1
2
let obj = { 'name': 'frank', 'age': 18 }
let obj = new Object({ 'name': 'frank'})

注意:

  • 键名是字符串,不是标识符,可以包含任意字符
  • 引号可以省略,省略之后就只能写标识符
  • 就算省略了引号,键名也还是字符串

变量做属性名

写法

1
2
let p1 = 'name'
let obj = {[p1]:'frank'}    //属性名为'name'

对比

  • 不加 [] 的属性名会自动变成字符串
  • 加了 [] 则会当作变量,先求值再变字符串
  • 值如果不是字符串,则会自动变成字符串

对象的增删改查

删除属性

1
2
3
4
5
6
delete obj.xxx
delete obj['xxx']
//可删除 obj 的 xxx 属性(键和值)

obj.xxx = undefined
//让 obj 的 xxx 属性值为 undefined,键还在

确认对象是否存在某个属性

1
2
3
4
5
6
7
8
9
'xxx' in obj === false
//obj 不含 xxx 这个属性

'xxx' in obj && obj.xxx === undefined
//obj 有 xxx 这个属性,但是值为 undefined

obj.xxx === undefined
//不能断定 'xxx' 是否为 obj 的属性
//因为可能属性有值,值为 undefined

读属性(查看)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Object.keys(obj)
//查看对象自身有的属性

Object.values(obj)
//查看对象自身属性的值

Object.entries(obj)
//查看对象自身的属性和值

console.dir(obj)
//查看对象的共有属性

obj.hasOwnProperty('key')
//查看对象自身有没有某个属性

obj['key']  //查看属性的值,中括号语法
obj.key     //查看属性的值,点语法
obj[key]    //变量 key,要先求变量的值,再把值变成字符串

写属性(修改或增加)

直接赋值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let obj = {name: 'frank'}
//先创建变量

obj.name = 'frank'
obj['name'] = 'frank'
obj['na' + 'me'] = 'frank'
//然后赋值,name是字符串,三种写法都可以

let key = 'name'
obj[key] = 'frank'
//也可以先创建一个变量 'name',再赋值

批量赋值

1
2
Object.assign(obj,{p1:1,p2:2,p3:3})
//给 obj 创建三个属性同时赋值

无法在自身修改或增加共有属性,直接操作的共有属性会写在自己身上。如果想要修改共有属性,用下面的方法:

1
2
Object.prototype.toString = 'xxx'
//把所有 Object 的隐藏属性 toString 改为 ‘xxx’

对象的隐藏属性

每一个对象都有一个隐藏属性,这个隐藏属性储存着对象的 共有属性组成的对象的地址,这个共有属性组成的对象就是 原型

原型

每个对象都有原型,原型里存着对象的共有属性,obj.__proto__ 存着共有属性组成的对象的地址,这个对象里有 toString constructor valueOf 等共有属性。

对象的原型也是对象,obj = {} 的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根,对象的根这个原型也有原型,值为 null

原型链

1
2
3
4
5
6
7
8
let obj = Object.create(xxx)
obj.name = 'frank'
//以 xxx 这个对象作为 obj 的原型创建 obj 对象,然后给 obj 创建name属性并赋值

let obj = Object.create(xxx,{
    name:{value:'frank'}	
})
//以 xxx 这个对象作为 obj 的原型创建 obj 对象同时增加属性并赋值

这样创建的 obj 的原型是xxx,而xxx 的原型是对象的原型,这样就形成了一个原型链。

细节

Q:'name' in objobj.hasOwnProperty('name') 的区别

A:这两种方法都可以查看 obj 是否含有 'name'属性,返回值为 truefalse,他们两个区别是 hasOwnProperty 仅仅判断 obj本身的属性是否含有 'name',而 in也会去对象的原型里去找是否含有该属性。

MDN文档:所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会 忽略掉那些从原型链上继承到的属性

资料来源:饥人谷、MDN