JS对象基本用法

128 阅读3分钟

JS对象

  • 定义

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

    • let object = {'name':'tom','age':18}
    • let object = new Object({'name':'tom','age':18})
    • console.log({"name":"tom","age":18})
  • 细节

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

可以通过Object.keys(对象名) 就可以得到对象的所有key

每个key都是对象的属性名,每个value都是对象的属性值

变量作属性名

  • 如何用变量做属性名

    • 之前都是用常量做属性名
 let p1 = 'name'
 let obj = {p1:'Wilson'} //这样写,属性名为p1
 let obj = {[p1]:'wilson'} //这样写,属性名为name
  • 对比

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

对象的隐藏属性

  • 隐藏属性

    • JS中每一个对象都有一个隐藏属性
    • 这个隐藏属性存储着其共有属性组成的对象的地址
    • 这个公有属性组成的对象叫做原型
    • 也就是说,隐藏属性存储着原型的地址
  • 代码示例

 var obj = {}
 obj.toStirng() //没有报错
 //因为obj的隐藏属性对应的对象上有toString()

增删改查

删除属性
  • delete obj .xxx 或 delete obj['xxx']

    • 即可删除obj的xxx属性
    • 请区分[属性值为 undefined] 和 [不含属性名]
  • 不含属性名

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

    • ‘xxx’ in obj && obj .xxx === undefined
  • 注意 obj .xxx === undefined

    • 不能断定'xxx'是否为obj的属性
  • 类比

    • 你作业呢

      A:没写//不含属性名

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

    • 没有就是没有,undefined就是undefined绝不含糊

查看属性
  • 查看自身所有属性

    • Object.keys(object)
  • 查看自身+共有属性

    • console.dir(object)
    • 或者自身依次用Object.keys打印出obj. __ proto __
  • 判断一个属性是自身的还是共有的

     obj.hasOwnProperty('toStirng')
    

原型

  • 每个对象都有原型

    • 原型里存着对象的共有属性
    • 比如object的原型就是一个对象
    • object._ proto_ 存着这个对象的地址
    • 这个对象里有toString/constructor/valueOf等属性
  • 对象的原型也是对象

    • 所有对象的原型也有原型
    • object = {} 的原型即为所有对象的原型
    • 这个原型包含所有对象的共有属性,是对象的根
    • 这个原型也有原型,是null
直接通过对象查看属性
  • 两种方法查看属性

    • 中括号语法:object['key']
    • 点语法:object.key
    • 坑新人语法:object[key] //变量key值一般不为'key'
  • 请优先使用中括号语法

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

修改或增加属性

  • 直接赋值
 let object = {name:'wilson'} //name是字符串
 object.name = 'wilson'
 object['name'] = 'wilson'
 let key = 'name';object[key] = 'wilson';
  • 批量赋值
 Object.assign(object,{age:18,gender:'man'})

修改或增加共有属性

  • 无法通过自身修改或增加共有属性
 let object={}; object2={} //共有toString
 object.toString='xxx' 只会在改object自身属性
 object2.toString还是在原型上
  • 我如果偏要修改或增加原型上的属性
 object._proto_.toString = 'xxx' 
 Object.prototype.toString = 'xxx'
 //一般来说,不要修改原型,会引起很多问题,而所有_proto__代码都是强烈不推荐写的

修改隐藏属性

  • 不推荐使用_proto _
 let obj={name:'wilson'}
 let obj2={name:'Tom'}
 let common = {kind:'human'}
 obj._proto_ = common
 obj2._proto_ = common
  • 推荐使用Object.create
 let obj = Object.create(common)
 obj.name= 'frank'
 let obj2 = Objext.create(common)
 obj2.name = 'jack'
 //规范大概的意思是,要改就一开始就改,别后来再改
'name' in obj 和obj.hasOwnProperty('name')的区别

'name' in obj 返回的是一个bool值,判断属性名是否存在对象obj中

obj.hasOwnProperty('name')判断name属性是不是obj对象独有的,而不是共有属性