【JavaScript】数据类型-对象

189 阅读4分钟

一、object 是一种复杂数据类型

其它6种简单数据类型(四基两空一对象)

  • number
  • string
  • boolean
  • symbol
  • null
  • undefined

定义

对象是无序的键值对的数据集合。

写法

  • let obj = {'name':'lu','age':18} 简写
  • let obj = new Object({'name':'lu'}) 正规写法
  • console.log({'name':'lu','age':18}) 匿名对象,直接打印出来

细节

键名只能是字符串,可以包含任意字符,其引号可以省略,省略后的命名规则遵从标识符的规则,但类型依然是字符串

举例

var obj = {
	100:'888';
}

对象obj的键的引号被省略,且是字符串'100',不是数字100

属性名

每个键(key)都是对象的属性名(property),以下是一些特殊的属性名

let obj = {
	1:'a',
    3.2:'b',
    1e2:true, //1e2=1*10^2
    1e-2:true,
    .234:true,
    0xFF:true,
};
Object.keys(obj) //得到一个对象所有的key

输出:['1','100','255','3.2','0.01','0.234']

属性值

每个值(value)都是对象的属性值,属性值可以是任何值,undefined表示value不存在,null表示存在,但是为空

如何用变量作属性名?

let a = 'name'; 
let obj = {a:100}; //这里定义的对象的key其实是'a'
let obj = {[a]:100}; //这里定义的对象的key就是变量a的值'name'

不加[]的属性名会自动变成字符串,加上[]会对变量求值

对象的隐藏属性

  • JS中每一个对象都有一个隐藏属性(一个隐藏键值对)
  • 这个隐藏属性的value存储着一个地址,这个地址指向一个新的对象,新的对象存储着所有共有属性,这个新的对象叫做原型,即隐藏属性存储着原型的地址

二、object属性的增删改查

删属性

以下两种方法都可以删除对象obj的xxx属性

  • delete obj.xxx
  • delete obj['xxx'] //注意xxx的单引号,证明其是字符串
  • 'xxx' in obj //若返回false,则证明删除obj中的xxx属性成功,但是无法分辨xxx是自身属性还是共有属性
  • obj.hasOwnProperty('xxx') //判断xxx是不是obj的自身属性

区分delete和===undefined

  • delete obj.xxx 删除整个属性,属性不存在了,使用'xxx' in obj 判断属性obj中还有没有'xxx'属性名,返回false
  • obj.xxx === undefined //无论obj中有没有xxx属性,都会返回true,所有obj.xxx === undefined无法判断obj中是否有xxx属性,应该使用in

查属性

查看所有属性

  • Object.keys(obj) 查看对象obj的所有自身属性的key(同理,Object.values(obj)可以查看对象obj的所有值)
  • console.dir(obj) 通过目录的形式查看对象obj的所有自身属性+共有属性

查看单个属性

  • 中括号语法:obj['key'] (优先使用)
  • 点语法:obj.key (谨慎使用,看上去key不是一个字符串,然而所有的key必须是字符串)
  • 避坑:obj[key],错误写法,这里的key是个变量,其值不确定

修改或增加自身属性

通过赋值直接修改自身属性

  • let obj = {name:'lu'}; 这里的name是一个字符串
  • obj.name = 'lu' 或 obj['name'] = 'lu' 这里的name是一个字符串

批量修改自身属性

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

修改或增加共有属性(原型属性)

无法增加或修改共有属性

  • let obj={},obj2={} //此时obj和obj2有相同的共有属性
  • obj.toString='xxx' //试图在obj上修改toString共有属性,其实是增加了一个toString自身属性,不会覆盖原型中的toString属性
  • obj2和obj的原型中依然有toString属性
  • 一般,不要修改原型

修改隐藏属性

推荐使用Object.create

  • 在创建对象的时候就修改隐藏属性,let obj = Object.create(common);
  • 然后向对象中追加键值对,obj.name = 'lu';
  • 或者批量追加,Object.assign(obj,{name:'lu',age:'18'});

三、原型

每个对象都有原型

  • obj.__proto__存着对象obj的原型的地址
  • 对象obj的原型也是一个对象
  • 这个对象里存着对象obj的所有共有属性,比如toString/constructor/valueOf

对象的原型也是对象

  • 所有对象的原型也都有一个原型,但是这个原型的value(地址值)指向null,所以这个原型是根对象