JS 对象的概念

229 阅读3分钟

本章很重要,要重视啊啊啊啊



〇、热身

  • 七种数据类型

  1. number
  2. string
  3. bool
  4. symbol
  5. null
  6. undefined
  7. object
  • 五个falsy值

  1. null
  2. undefined
  3. 0
  4. NaN
  5. '' (空字符串)

一、对象 object

定义

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

写法

let obj={'name':'frank','age':18}
let obj=new Object({'name':'frank'})
console.log({'name':'frank','age':18})        匿名对象

特别注意!

  • 键名是字符串,不是标识符,可以包含任意字符,包括中文、符号等等
  • 引号可以省略,但是省略后只能写标识符
  • 就算引号省略了,键名也依旧是字符串


二、属性名和属性值

属性名:每个key都是对象的属性名(property)

属性值:每个value都是对象的属性值

let obj={
    1:'a'
    3.2:'b'
    1e2:true
    1e-2:true
    .234:true
    0xFF:true
};
Object.keys(obj)=
["1","3.2","100","0.01","0.234","255"]

细节:

Object.keys(obj)可以得到obj所有的key


变量作属性名

let pl = 'name'
let obj={pl:'frank'}
let obj={[pl]:'frank'}

第二句和第三句的区别十分重要:

第二句的pl是字符串,属性名为'pl'

第三句的[pl]是指将pl变量的字符串名带进去,属性名为'name'

不加[]属性名会自动变成字符串

加了[]则会当作变量求值

值如果不是字符串,则会自动变成字符串


In addition,除了字符串,symbol也能做属性名(symbol赋予了a一个独特的的值)

let a=Symbol()
let obj={[a]:'Hello'}

对象是有隐藏属性的!

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


三、增删改查

删除属性

delete obj.xxx
delete obj['xxx']

注意:obj.xxx=undefined 这个操作,会让xxx属性值为空,但是属性依旧还在

1. 检验是否含有该属性名

'xxx' in obj === false  //不含有该属性名

2. 含有属性名,但是值为undefined

'xxx' in obj && obj.xxx ===undefined 
//含有该属性名,但是值为空,undefined

3. 注意obj.xxx===undefined

不能断定'xxx'是否为obj的属性,有可能没有,也有可能冇得(但是为空)


查看所有属性(读属性)

1. 查看自身所有属性

Object.keys(obj)

2. 查看自身属性+共有属性

console.dir(obj)
或者用Object.keys打印出 obj.__proto__

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

obj.hasOwnProperty('toString')

原型

每个对象都有原型

  1. 原型里存着对象的共有属性
  2. 比如obj的原型就是一个对象
  3. obj.__proto__存着这个对象的地址
  4. 这个对象里有toString/constructor/valueOf等属性

对象的原型也是对象

  1. 所以对象的原型也有原型
  2. obj={}的原型即为所有对象的原型
  3. 这个原型包含所有对象的共有属性,是对象的根
  4. 原型也有原型,是null

查看属性

两种方法查看属性

1. 中括号语法:obj['key']

2. 点语法:obj.key

3. 坑新人语法:obj[key]

//变量key值不为'key'


请优先使用中括号语法

点语法会误导你,让你以为 key 不是字符串 等你确定不会弄混两种语法,再改用点语法

题目:

let list = ['name', 'age', 'gender']
let person = {
       name:'frank', age:18, gender:'man'}
for(let i = 0; i < list.length; i++){
  let name = list[i]
  console.log(person__???__)
}

选项:

  1. console.log(person.name)

  2. console.log(person[name])

选 2.


四、批量赋值

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

五、修改或增加共有属性

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

let obj={},obj2={} //共有toString
obj.toString='xxx' //只改obj自身的属性
obj2.toString      //还是在原型上,不变

· 我偏要修改或增加原型上的属性

obj.__proto__.toString = 'xxx' // 不推荐用 __proto__
Object.prototype.toString = 'xxx' 

一般来说,不要修改原型,会引起很多问题



六、修改隐藏属性

· 不推荐使用__proto__

let obj = {name:'frank'}
let obj2 = {name: 'jack'}
let common = {kind: 'human'}
obj.__proto__ = common
obj2.__proto__ = common

· 推荐使用Object.create

let obj = Object.create(common)
obj.name = 'frank'
let obj2 = Object.create(common)
obj2.name = 'jack'

规范大概的意思是,要改就一开始就改,别后来再改