JS 对象基本用法

85 阅读4分钟

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

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

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

obj.key //点语法

obj['key'] //中括号语法

1. 声明对象的两种语法

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

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

2. 如何删除对象的属性

delete obj.xxx 

delete obj['xxx']

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

用法:delete obj.xxxdelete obj['xxx'],即可删除 obj 的 xxx 属性。其中undefined删除的是值,delete删除的是属性名

请区分「属性值为 undefined」和「不含属性名」

  • 不含属性名 'xxx' in obj === false
  • 含有属性名,但是值为 undefined 'xxx' in obj && obj.xxx === undefined

注意 obj.xxx === undefined,不能断定'obj'是否为obj的属性,只能判断属性值为undefined。

'xxx' in obj 用来判断属性名是否还在,返回false,删除成功;'xxx' in obj&&obj.xxx 返回undefined证明含有属性名,但是值为undefined。

类比:——你有没有卫生纸?

A: 没有 // 不含属性名

B: 有,但是没带 // 含有属性名,但是值为 undefined

3. 如何查看对象的属性

Object.keys(obj) //查看自身所有属性

console.dir(obj) //查看自身+共有属性

obj.hasOwnProperty('toString') //判断一个属性是自身的还是共有的

'toSrting' in obj   //用来看是否存在该属性,但是不知道是谁的
let obj = { 'name': 'frank', 'age': 18 }
Object.keys(obj)     //查看所有属性
// ['name', 'age']
Object.values(obj)   //查看所有属性值
// ['frank', 18]
Object.entries(obj)  //查看所有key和value
// [Array(2), Array(2)]

obj.name 等价于 obj['name'],简单来说,这里的 name 是字符串,而不是变量

let name = 'frank'obj[name] 等价于obj['frank']

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.name)
}

// 打出三个frank

person.name里面的name 是字符串,所以只会打出name字符串对应的'frank'

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[name])
}
// frank
// 18
// man

person[name]里面的name 是变量,person[name]会被替换成person.nameperson.ageperson.gender

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

obj['name'] = 'jack' //直接赋值,改自身

Object.assign(obj, {age:18, ...}) //批量赋值,改自身

obj.__proto__['toString'] = 'xxx' //改共有属性,不推荐

Object.prototype['toString'] = 'xxx'//改共有属性

obj.__proto__ = common//改原型,不推荐

let obj = Object.create(common) //改原型
  • 直接赋值 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']

  • 批量赋值 Object.assign(obj, {age: 18, gender: 'man'})

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

查看属性名name是否存在:'name' in obj 控制台的输出为false或true; 判断属性name是自身的还是共有的:obj.hasOwnProperty('name'),输出为false或true。

'name' in obj不能判断是否是自身属性,obj.hasOwnProperty('name')可以判断。

6.原型

  • 每个对象都有原型 原型里存着对象的共有属性,比如 obj 的原型就是一个对象,obj.__proto__ 存着这个对象的地址 这个对象里有 toString / constructor / valueOf 等属性
  • 对象的原型也是对象 所以对象的原型也有原型,obj = {} 的原型即为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根,这个原型也有原型,是 null。

7.总结

  • delete obj['name']

'name' in obj // false

obj.hasOwnProperty('name') // false

  • Object.keys(obj)

console.dir(obj)

obj['name']

obj.name // 记住这里的 name 是字符串

obj[name] // 记住这里的 name 是变量

  1. 改自身 obj['name'] = 'jack'
  2. 批量改自身 Object.assign(obj, {age:18, ...})
  3. 改共有属性 obj.__proto__['toString'] = 'xxx'
  4. 改共有属性 Object.prototype['toString'] = 'xxx'
  5. 改原型 obj.__proto__ = common
  6. 改原型 let obj = Object.create(common)
  7. 注:所有__proto__代码都是强烈不推荐写的
  • 增 基本同上:已有属性则改;没有属性则增。

问题:

let obj = Object.create({name:'frank'})和 let obj1 = new Object({name:'frank'})的区别是什么

let obj = Object.create({name:'frank'})的属性是在原型上,Object.create是改变了原型的属性。

let obj1 = new Object({name:'frank'})的属性是自身的

image.png obj.xxx === undefined不能判断xxx在不在obj里面

只能用'xxx' in obj 来判断。