JS对象

268 阅读4分钟

对象的定义与写法

  1. 定义
  • 无序的数据集合
  • 键值对的集合
  1. 写法
let obj = {'name':'care', 'age':18} //简洁易用
let obj = new Object({'name':'care', 'age':18})//正规但繁琐
console.log({'name':'care', 'age':18}) //匿名对象,如果没有console.log()则不是对象,而是一个标签
  1. 细节
  • 键名是字符串,不是标识符,可以包含任意字符
  • 引号可省略,但省略之后只能写标识符
  • 就算省略了引号,键名也还是字符串
  1. 属性名 属性名会自动转换为字符串,数字会自动转换为十进制的数字对应的字符串
  • 1 -> '1'
  • 2.3 -> '2.3'
  • 1e2 -> '100'
  • 1e-2 -> '0.01'
  • .234 -> '0.234'
  • 0xFF -> '63' Object.keys(obj)可以得到obj的所有key。
  1. 使用变量作为属性名
let p1 = 'name'
let obj = {p1:'care'}//属性名为p1
let obj = {[p1]:'care'}//属性名为name

对比可得:不加[]则默认是字符串,只有加了[]才会被当做变量,其值如果不是字符串,则自动转换为字符串。

对象的隐藏属性

  1. 隐藏属性
  • JS中每一个对象都有隐藏属性
  • 这个隐藏属性储存着其共有属性组成的对象的地址
  • 这个共有属性组成的对象叫做原型
  • 换言之,隐藏属性储存着原型的地址 obj.toString()中,obj的隐藏属性对应的对象上有toString()

删除属性

1、delete obj.xxx 或 delete obj['xxx'] 删除obj的xxx属性

let obj = {
	'name':'care',
    'age':18
    }
delete obj.name

trap:

  • 需要区分属性值为undefined不含属性值,前者仅删除了属性值,后者同时删除了属性名和值ob
  • obj.xxx === undefined 不能用来判断obj是否含有xxx属性,因为没有该属性时也返回undefined。 tip:
  • 用·xxx' in obj ===false则可以判断xxx属性名不在obj里面
  • 含有属性名,但是值为undefined:'xxx' in obj && obj.xxx === undefined

查看对象属性

  1. 查看自身所有属性
  • Object.keys(obj) 查看自身所有属性
  • Object.values(obj) 查看自身所有值
  • Object.entries(obj) 返回两个数组,一个为所有属性,一个为所有值
let obj = {
	'name' : 'hlc',
    'age' : 18
    }
Object.keys(obj)
  1. 查看自身属性与共有属性
  • console.dir(obj)
  • 依次用Object.keys打印出obj.__proto__
obj.__proto__.toString //查看obj的toString属性
  • 判断属性为自身还是共有:obj.hasOwnProperty('toString'),true表示为自身属性
  • 查看自身某个属性:1. 中括号语法:obj['key'] 2. 点语法:obj.key 优先使用中括号语法,防止字符串混淆。

原型

  1. 每个对象都有原型
  • 原型中存着对象的共有属性
  • 如obj的原型为一个对象,obj.__proto__存着这个对象的内存地址,这个对象里有toString/constructor/valueOf等属性
  1. 对象的原型也是对象
  • 推出:对象的原型也是原型
  • obj={}的原型即为所有对象的原型,该对象包含所有对象的共有属性,是对象的根,该原型也有原型,是null

修改或增加属性(写属性)

  1. 直接赋值
let obj = {name:'hlc'} //name是字符串
obj.name = 'hlc' //name是字符串
obj['name'] = 'hlc'
let key = 'name'; obj[key] = 'hlc' // key是赋值的变量,不用加引号
  1. 批量赋值
Object.assign(obj,{age:18,gender:'man'})
  1. 修改或增加共有属性
  • 无法通过自身修改或增加共有属性(只有读会去看隐藏属性对于原型,写不走原型)
  • 可以有其他方法修改原型,但是 一般来说不要修改原型,会有很多问题

修改原型的方法

  • 第一种:直接在原型上面改(修改共有属性),这样所有对象引用该原型都会被影响
obj.__proto__.toString='xxx'  //修改共有原型的toString属性为'xxx'
Object.prototype.toString='xxx'  //从总原型自上往下找到然后修改
  • 第二种,对象还没出来就先创建好原型,创建的时候再指定
var common = {
  '国籍': "中国",
  '省份': "广东",
};   //创建一个对象
var obj=Object.create(common)  //以对象common为原型创建对象obj
obj.name='hlc'   //给对象obj添加属性
obj.爱好='code'   //添加属性,也可以批量修改

obj的原型为common,common的原型为Object.__proto__所指向的原型,由此形成原型链,common可看成在原有原型链中增加的一个节点。