JS对象基本用法

Object

对象就是一组”键值对“(key-value)的集合,是一种无序的复合数据集合。

1
2
3
4
5
6
7
8
9
let obj = {
'name': 'frank',
'age': 18
}
let obj = new Object({
name: 'frank',
age: 18
})
console.log({name: frank, age: 18})
  • 键名都是字符串,不是标识符,可以包含任意字符(必须加上引号)
  • 引号可以省略,省略后键名必须符合标识符的规则
  • 所有键名都会被自动转成字符串

特殊键名

1
2
3
4
5
6
7
8
9
10
let obj = {
1: 'a',
3.2: 'b',
1e2: true,
1e-2: true,
.234: true,
0xFF: true
};
Object.keys(obj) // 列出 obj 所有的 key
=> ["1", "100", "255", "3.2", "0.01", "0.234"]

用变量做键名 用 [ ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let p1 = 'name';
let obj = {
p1: 'frank' // 键名为 'p1'
}

let obj = {
[p1]: 'frank' // 键名为 name
}
// 不加 [] 的键名会自动变成字符串
// 加了 [] 则会当作变量求值
// 值如果不是字符串,则会自动变成字符串
var obj {
[1+2+3]: 'shi'
}
Object.keys(obj);

隐藏属性

  • JS中每一个对象都一个隐藏属性 _proto_
  • 这个隐藏属性存储着共有属性组成的对象的地址
  • 这个共有属性组成的对象叫做原型
  • 也就是说,隐藏属性存储着原型的的地址

示例

1
2
3
4
// 隐藏属性为 __proto__
var obj = {}
obj.soString() // 不报错
因为 obj 的隐藏属性 对应的对象 上有 toString()

删除属性

delete obj.xxx 或 delete obj[‘xxx’]

可删除 obj 的 xxx 属性

区分 【属性值为 undefined】和【不含属性名】

不含属性名

‘xxx’ in obj === false

含有属性名,但是值为 undefined

‘xxx’ in obj && obj.xxx === undefined

注意 obj.xxx === undefined

不能断定 ‘xxx‘ 是否为 obj 的属性


读取属性

查看属性

obj[‘key’]

obj[key]

obj.key

obj.name 等价于 obj[‘name’] 不等价于 obj[name] 这里的 name 是字符串,不是变量

查看自身所有属性

Object.keys(obj);

查看自身 + 共有属性

console.dir(obj)

或者依次用 Object.keys 打印出 obj._proto_

判断一个属性是自身的还是共有

obj.hasOwnProperty(‘toString’)

1
2
3
4
Object.keys(obj);
Object.values(obj);
Object.entries(obj);
console.dir(obj);

‘name’ in obj 和 obj.hasOwnPrototy(‘name’) 区别

前者判断 obj 是否含有 name 属性名,但不会区分自身属性和共有属性

后者判断 obj 的属性 name 是自身的属性还是共有属性,返回 false,不是自身属性;发返回 ture,是自身属性。


#### 原型

每个对象都有原型

原型里存着对象的共有属性

比如 obj 的原型就是一个对象

obj.__proto__存着这个对象的地址

这个对象里有 toString / constructor / valueOf 等属性

对象的原型也是对象

所以对象的原型也有原型

obj = {} 的原型即为所有对象的原型

这个原型包含所有对象的共有属性,是对象的根

这个原型也有原型,是 null。 console.log(_proto._proto)


修改属性

直接赋值

1
2
3
4
5
6
7
8
let obj = {name: 'frank'} // name 是字符串
obj.name = 'frank' // name 是字符串
obj['name'] = 'frank'
❌obj[name] = 'frank' // 错,因 name 不确定
obj['na' + 'me'] = 'frank'
let key = 'name'; obj['key'] = 'frank'
let key = 'name'; ❌ obj.key = 'frank' // 错
因为 obj.key 等价于 obj['key']

批量赋值

1
Object.assign(obj.{age: 18, gender: 'man'})

修改或增加共有属性

无法通过自身修改或增加共有属性

1
2
3
let obj1 = {},obj2 = {}  // 共有toString
obj.toString = 'xxxx' // 只会改 obj1 自身的属性
obj2.toString 还是在原型上

偏要修改共有属性

1
obj1.__proto__.toString = 'xxx'; // 不推荐使用__proto__Object.prototype.toString = 'xxx';一般不要修改原型

修改隐藏属性

不推荐使用_proto_

1
2
3
4
5
6
// 代码示例
let person = {name: 'frank'};
let person1 = {name: 'jack'};
let common = {kind: 'human'};
obj.__proto__ = common;
obj2.__proto__ = common;

强烈推荐使用 Object.create

1
2
3
4
5
let persion = Object.cteate(common); // 以 common 为原型创建 persion 对象
persion.name = 'frank'; // 然后添加属性,或批量添加
let persion2 = Object.create(common, { //
name: {value: 'jack'}
});