JS 对象的基本用法(增删改查)

773 阅读4分钟

声明对象

1. 声明对象的两种语法

第一种写法:

let obj = {
    'name' : 'meng',
    'age' : 18
}

第一种写法:

let obj = new Object({ 
  'name' : 'meng', 
  'age' : '18' 
})

两种语法都可以用,第一种相对于第二种简单一些,所以第一种用的多

  • 注意
    • 对象都是以键值对的形式出现
    • 键名是字符串,不是标识符,可以包含任意字符串
    • 引号可以省略,省略之后只能按标识符的规则写(数字除外)
    • 就算引号省略了,键名也还是字符串
    • 当键名有空格,中文等特殊符号是,必须加引号,否则会出错
    • 没有数字键名,也没有数字下标,因为浏览器会自动把数字转换成字符串

2. 属性名(keys)

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

除了上述介绍的键名命名规则,这里还有几个有奇怪 的属性名

let obj = {
    1: 'a',
    3.2: 'b',
    1e2: true,
    1e-2: true,
    .234: true,
    0xFF: true
}

在浏览器上打印出 obj 的属性名,结果如下

不难看出只有 1 和 3.2 没有变化

其他的键名都被浏览器进行了运算

所以建议在有特殊字符,或者有非英文的键名上不要省略引号

3. 变量作属性名

let p1 = 'name'
let obj = {p1: 'frank'} // 这样写,属性名为 'p1'
let obj2 = {[p1]: 'frank'} // 这样写,属性名为 'name'
复制代码
  • 对比

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

4. 对象的隐藏属性

代码示例

let obj = {}
obj.toString() // 不报错
// 因为 obj 的隐藏属性对应的对象上有 toString()
复制代码

这种隐藏属性叫做对象的原型

原型要注意以下几点:

  • 每个对象都有原型

  • 对象的原型也是对象

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

可能会有点绕,我用代码解释一下

proto__的__proto

对象的增删改查

1. 如何删除对象的属性

let obj = {
    name: 'meng',
    age: '18',
    gender: 'man'
}
obj.name = undefined // 把 name 属性设置为 undefined
delete obj.name // 删除属性

上述代码请区分属性值为 undefined 和 不含属性名

  • 不含属性名

    • 可以用下面代码验证对象是否含有此属性
'name’ in obj === false
  • 含有属性名,但是值为 undefined

    • 可以用下面代码验证含有属性且属性的值为 undefined
'name' in obj && obj.name === undefined
//  obj.name === undefined 不能判断 name 是否为 obj 的属性,所以要做一个 && 运算

注意:把属性设置为 undefined 不是删除此属性,只是改变了属性的值,这个要和 delete 区分开

2. 如何查看对象的属性

查看所有属性

  • 查看自身所有属性
let obj = {
    name: 'meng',
    age: 18
}
Object.keys(obj) // 查看所有键
Object.values(obj) // 查看所有值
Object.entries(obj) // 查看键和值
  • 查看自身和共有属性
console.dir(obj)
Object.keys(obj.__proto__) // 不推荐用这种方法
  • 判断一个属性是自身还是共有的
obj.hasOwnProperty('toString')

如果返回值为 false,那么这个属性就不是自身的属性

反之,返回 true 的话这个属性就是自身的属性

查看单个属性

  1. 中括号语法
obj['key']
  1. 点语法
obj.key
  1. 上两种方法的变体
let key = ‘xxx’
obj[key] // key 为变量

新手建议使用第一种方法,明确且不会入坑

3 & 4. 如何修改或增加对象的属性

  • 直接赋值
let obj = {
    'name': 'frank'
}
obj.name = 'meng' // 修改属性
obj.age = 13 // 增加属性
// 如果对象有此属性就为修改,没有此属性就为增加

这是一个一个赋值,有时候可能会很麻烦,新版的 ES6 就提供了一个 API 用于添加多个属性


  • 批量赋值
let obj = {}
Object.assign( obj, {'name':'meng', 'age': '18'})
  1. 使用 proto 修改
var common = { '国籍':'中国',hairColor:'black'}
var person = {jj: '11'}
person.__proto__ = common // 把原型的地址改成 common 的地址
复制代码

💥2. 使用 ES6 新的 API 来修改原型

var common = { '国籍':'中国',hairColor:'black'}
var person = Object.create(common)
let obj = Object.create(common) 
obj.name = 'frank' 
let obj2 = Object.create(common) 
obj2.name = 'jack'

推荐使用第二种 ES6 新 API,因为第一种会有性能问题

无法通过自身修改或增加自有属性
let obj = {}
let obj2 = {}         //obj和obj2共有toString
obj.toString = 'xxx'  //只会修改Obj自身属性,obj2.toString还在原型上

偏要修改或增加原型上的属性
obj.__proto__.toString = 'xxx'   //比推荐使用__proto__
Object.prototype.toString = 'xxx'
-- 一般来说,不推荐修改原型,会引起很多问题

总结一句话,所有 "proto" 代码都是强烈不推荐写的

5. 'name' in obj和obj.hasOwnProperty('name') 的区别

都是两种查看属性是不是在对象里的方法
前者自身属性和共有属性都返回true,后者仅仅是自身属性才返回true

12091993-f1df3900425e5450.png