ES5将对象属性分为:
命名属性: 可用.直接访问到的属性
数据属性: 直接存储属性值的属性
保护数据属性: 4大特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
一个属性包含四大特性:{
  value: 实际保存属性值,
  writable: true/false, //只读
  enumerable: true/false, //不可遍历
    //不是彻底隐藏,用.依然可访问!
  configurable:true/false //1. 禁止删除
                     //2. 禁止修改其它特性
                     //一旦改为false,不可逆
}
获取一个属性的四大特性:
var attrs=Object.getOwnPropertyDescriptor(obj,"属性")
修改四大特性:
Object.defineProperty(obj,"属性",{
  四大特性:值
})
简写: Object.defineProperties(obj,{
       属性名:{
         特性:值,
         特性:值,
       },
       属性名:{
         ... : ...
       }
     })

  访问器属性: 不直接存储属性值,仅提供对另一个数据属性的保护
何时: 只要对一个属性提供自定义规则的保护
如何:

1
2
3
4
5
6
7
8
9
10
11
12
添加: 只能用Object.defineProperty和defineProperties添加
四大特性: {
  get(){ return this.数据属性 }
  set(val){
    如果验证val通过
      this.数据属性=val
    否则
      报错
  }
  enumerable:
  configurable:
}

  

如何使用: 同普通的数据属性用法一样!

1
2
在取值时,自动调用访问器属性内部的get
在赋值时,自动调用访问器属性内部的set方法,同时将等号右边的新值,交给val参数

问题: enumerable只能防住for in,防不住.,依然可用.直接修改被保护的数据属性
解决: 
内部属性: 不能用.直接访问到的属性
比如: class proto

保护对象的结构: 3种

    1. 防扩展: 禁止给对象添加新属性
      Object.preventExtensions(obj)
      原理: 内部属性: extensible:true

      1
      preventExtensions将extensible改为false
    2. 密封: 在防扩展同时,禁止删除现有属性
      Object.seal(obj)
      原理: 

      1
      2
      3
      1. 将extensible改为false,禁止扩展
       
       2. 自动将所有属性的configurable都改为false
    3. 冻结: 在密封的同时,禁止修改一切属性值
      Object.freeze(obj)
      原理:

      1
      2
      3
      1. 兼具密封的所有功能
       
      2. 又将每个属性的writable自动改为false!
    1. Object.create()
      仅用父对象,就可创建子对象, 
      同时还可为子对象扩展自有属性
      var child=Object.create(father,{
      //Object.defineProperties
      属性名:{

      特性:值,
      特性:值,

      }
      })
      鄙视: 描述Object.create的执行原理

      1. 创建空对象child
      2. 自动设置child的__proto__为father
      3. 为child扩展新的自有属性