js学习日记-对象字面量

一、对象字面量语法

var person={
    name:'小王',
    age:18,
    _pri:233
} 
  • 成员名称的单引号不是必须的
  • 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误
  • 成员名相同会发生什么?

es5普通模式下后定义的会覆盖前面定义的,严格模式则会报错

es6则不管什么模式都采用后面的覆盖前面的

  • 成员名可以是动态变量吗?

es5只能在对象字面量表达式申明以后再添加

     var dynamicVar="dyna";
     var person={
     }
     person[dynamicVar]='123';
     console.log(person[dynamicVar])

 es6则更符合使用场景,可在表达式内创建动态的成员名

     var dynamicVar="dyna";
     var person={
       [dynamicVar]:'test'
     }
     console.log(person[dynamicVar])

es6中如果想使用表达式外面的变量名作为成员名,变量的值作为成员值,可进一步简写为

     var dynamicVar="dyna";
     var person={
       dynamicVar, //这是一个语法糖,js引擎会解释为dynamicVar:'dyna'
       age:15
     }
     console.log(person.dynamicVar)

  注意:此时不能采用person[dynamicVar]方式访问,因为这句话js引擎会解释为person['dyna'],对象中没有dyna属性,肯定就是undefined了

  •  可以采用new person()的方式使用吗?

肯定是不可以,new关键字后面必须是一个构造函数才行,对象字面量哪来的构造函数

二、对象属性描述符

对象属性描述符有两种主要形式:

数据描述符存取描述符数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。

存取描述符是由getter-setter函数对描述的属性。

 

Object.getOwnPropertyDescriptor()或getOwnPropertyDescriptor()-读取属性的描述

Object.definePropertype或Object.defineProperties----设置属性的描述

当属性是采用Object.definePropertype创建时,省略的描述符会拥有默认值,布尔值的字段的默认值都是falsevaluegetset字段的默认值为undefined

var parent={}
Object.defineProperty(parent,'name',{})
console.log(Object.getOwnPropertyDescriptor(parent,'name'))  //{value: undefined, writable: false, enumerable: false, configurable: false}

当属性是直接是直接在对象中创建时,布尔值的字段默认都是true

var parent={
  name:'parent'
}
console.log(Object.getOwnPropertyDescriptor(parent,'name')) //{value: "parent", writable: true, enumerable: true, configurable: true}

 

数据描述符:

configurable-是否可以删除某个属性或修改属性的描述,为true时可进行操作,如果该属性先定义为false,后续又定义为true的话会报错

     Object.defineProperty(person,'name',{
       configurable:false
     })
     Object.defineProperty(person,'name',{
      configurable:true
     })
writable-属性是否可写
     Object.defineProperty(person,'name',{
       writable:false
     })
     person.name='小李'; //属性不可写,严格模式下会报错
     console.log(person.name); //输出小王,说明上面一句无效

enumerable-属性是否可被枚举,默认为false,该设置对于Object.getOwnPropertyNames()方法是无效的,对Object.keys()和for in有效。

使用相应的枚举方法,输出的结果是一个数组,那么数组中元素的顺序是按什么规则组织的呢?在es5中并没有明确这一点,各个浏览器有自己的实现,es6中采用Object.keys()和for in方法时还是没有明确,但采用Object.getOwnPropertyNames()方法枚举时,有了相应的标准:

  • 最先放入数组中的是数值型的成员名,按升序排列
  • 其次是其它类型的,按添加的先后顺序排列
     var obj={
       3:'我是1',
       1:'我是1',
       b:'我是b',
       a:'我是a'
     }
     var names=Object.getOwnPropertyNames(obj);
     console.log(names) //["1","3","b","a"]

value-该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined

 

存取描述符

get与set-读写成员时调用的函数,默认为undefined,如果只有get则表示属性值是只读的,只有set表示只能写。属性读写器最常用的场景就是在读取或写入属性前可以附带的做一些操作,达到更好的封装性。

     Object.defineProperty(person,'pri',{
       get:function(){
         //做一些其它操作
         console.log('准备获取_pri的值')
         return _pri;
       },
       set:function(newValue){
         _pri =newValue
       }
     })
     person.pri='456';
     console.log(person.pri);
 
某些描述符是相互排斥的,相应的关系见下表:

 

三、对象保护

  • 我不想让别人在我的对象上添加成员该怎么办?

Object.preventExtensions(),该方法用于阻止向对象添加成员,使用Object.isExtensible()判断对象是否可添加成员

    Object.preventExtensions(person);
    //添加成员无效,非严格模式下什么都不会发生,严格模式下会报错
    person.bankAccount='中国农业银行'
    //依然可以删除成员,证明了preventExtensions方法只能阻止添加方法
    delete person.age;
    console.log(person.age) //undefined,表明删除成功了
  • 我不想让别人添加、删除成员

Object.seal()用来阻止添加或删除成员,判断对象是否是密封的可采用Object.isSealed()

  • 我不想让别人添加、删除成员,也不想让别人对里面的成员进行赋值操作

使用Object.freeze()方法后,除了不能添加删除成员,连成员的赋值都会失效,但是写入属性(上面set定义的)依然是有效

方法禁止增加属性禁止删除属性禁止修改属性
Object.preventExtensions()
Object.seal()
Object.freeze()

   

posted @ 2018-06-13 18:19  我是格鲁特  阅读(4601)  评论(0)    收藏  举报