1.声明对象的两种语法

1.1.对象的定义

  • 无序的数据集合
  • 键值对的组集合

    1.2.写法

    1. let obj = {'name': 'frank','age': 18} //写法1,常用,但不正规
    2. let obj = new Object({'name': 'frank'}) //写法2,正规但不常用
    3. console.log({'name': 'frank','age': 18}) //console.log 不能省略,后面的花括号里的是表示一个对象

    1.3.注意细节

  • 键名是字符串,不是标识符,可以包含任意字符(中文,符号等)

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

    2.如何删除对象的属性

    1. delete obj.xxx
    2. delete obj['xxx']
    3. //删除 obj 的 xxx 属性

    2.1.区分 【属性值为 undefined】 和 【不含属性名】 是不一样的

    如何确认对象不含该属性名(in)

    1. 'xxx' in obj === false

    含有属性名,但是值为 undefined

    1. 'xxx' in obj && obj.xxx === undefined
  • [x] 另外 obj.xxx === undefined (这个只能用来判断属性值为 undefined ,不能来确定属性名)

不能断定 ‘xxx’ 是否为 obj 的属性,要用 in 来确定

2.2.类比

  • 你有没有卫生纸
  • A: 没有 // 不含属性名
  • [x] B: 有,但是没带 //含有属性名,但是值为 undefined

    3.如何查看对象的属性

    3.1.查看所有属性(读属性)

  • 查看自身所有属性

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

  • [x] 方法一

    1. console.dir(obj) //以目录的形式打出来
  • [x] 方法二(不推荐使用)

依次用 Object.keys 打印出 obj.proto

  • 判断一个属性是自身的还是共有的

    1. obj.hasOwnProperty('toString') //false 表示是共有属性

    将 toString 改为一个是自身的属性名,则会返回 true ,表示有这个属性

    3.2.查看单个属性

  • 两种方法

    1. 中括号语法:obj['key'] //新人优先使用这种
    2. 点语法:obj.key
  • 坑新人的语法

    1. obj[key] //这里的key是个变量,变量key的值一般不为 'key'
  • 注意

  • 点语法虽然写起来比较方便,但是会误导你,让你以为 key 不是字符串
  • 等到确定不会弄混两种语法,再改用点语法

    区分清楚 [‘name’] 和 [name]

  1. obj.name 等价于 obj['name']
  2. obj.name 不等价于 obj[name]
  • 这里的 name 是常量字符串而不是变量,[name] 表示的是变量 name
    1. let name = 'frank'
    2. obj[name] 等价于 obj['frank']
    3. 而不是 obj['name'] obj.name
    总的来说 ```javascript let obj = {name: ‘frank’} obj.name = ‘frank’ obj[‘name’] = ‘frank’ //以上三个 name 是字符串,[name] 这个 name 是变量

let key = ‘name’;obj[key] = ‘frank’ let key = ‘name’;obj.key !=’frank’ //因为 obj.key 等价于 obj[‘key’]

  1. <a name="zmLew"></a>
  2. ## 3.3.原型
  3. <a name="AqXOA"></a>
  4. #### 每个对象都有原型
  5. <a name="F1vHG"></a>
  6. #### 对象的原型也是对象
  7. - [x] 对象的原型包含所有对象的共有属性,叫做 **对象的根**
  8. - [x] 这个原型也有原型,原型的值是 null
  9. <a name="RKxD7"></a>
  10. # 4.如何修改或增加对象的属性(写属性)
  11. 已有属性则为改,没有的属性则为增
  12. <a name="ETPDL"></a>
  13. ## 4.1.修改或增加自身属性
  14. - 直接赋值
  15. ```javascript
  16. obj['name'] = 'frank'
  17. obj['na'+'me'] = 'frank'
  • 批量赋值
    Object.assign(obj,{age: 18, gender: 'man'})
    

    4.2.修改或增加共有属性(一般不要修改,会引起很多问题)

    两种方法如下:

    obj.__proto__.toString = 'xxx' //不推荐使用 __proto__
    Object.prototype.toString = 'xxx'
    
    注意:无法通过自身修改或增加共有属性,如下:
    let obj = {},obj2 = {}  //共有 toString
    obj.toString = 'xxx' //只会在改 obj 自身属性
    obj2.toString 还是在原型上
    

    4.3.修改隐藏属性

    4.3.1.推荐使用 Object.create

    语法:

    let obj = Object.create(common)
    
    示例:
    let obj = {'name': 'frank'}
    let obj2 = {name: 'jack'}
    let common = {kind: 'human'}
    let obj = Object.create(common)
    let obj2 = Object.create(common)
    
    结果 obj 和 obj2 都多了一层 proto ,如下图箭头所示
    image.png

    4.3.2.不推荐使用 proto

    语法:

    obj.__proto__ = common
    

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

共同点:返回的值都是只有布尔值

‘name’ in obj 是确认对象是否含有该属性名

  • 只要该属性在对象 obj 里,就返回 true ,反之返回 false

两张图都只赋值了 obj (let obj = {‘name’: ‘frank’})
image.png

obj.hasOwnProperty(‘name’) 是为了查看该属性是在对象自身,还是共有属性上

  • 该属性在对象自身,返回 true
  • 该属性在共有属性,或者不在自身,返回 false

image.png

总结:’name’ in obj 和 obj.hasOwnProperty(‘name’) 的区别在于

  • obj.hasOwnProperty(‘name’) 对于原型里的值返回 false
  • 而 ‘name’ in obj 返回 true