一、对象字面量语法

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.keys()和for in的,也就是说该属性设置对于Object.getOwnPropertyNames()方法是无效的。

使用相应的枚举方法,输出的结果是一个数组,那么数组中元素的顺序是按什么规则组织的呢?

在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()

四、其它技巧

  • 实现继承

Object.create(person)可产生一个具有继承特性的新对象,但是需要注意的是,父对象的引用类型成员是和子对象共享的,当子对象修改引用类型的成员时,父对象的该成员也会同步发生变化

     var person={
name:'小王',
age:18,
_pri:233,
gf:['豆得儿','张G','TFb']
}
var child=Object.create(person);
child.gf.splice(0,1); //跟豆得儿分手了
console.log(person.gf.length) //父类的gf也变成2了,父子共享女友,尼玛,太乱了

 es6中的Object.setPrototypeOf(obj, prototype)方法可将已有的对象变成继承关系,其内部原理也跟Object.create一样,都是将子对象的prototype指向父对象,该方法实现的继承依然有父子对象共享了引用类型成员的问题

     var person={
age:15
}
var man={ }
Object.setPrototypeOf(man,person)
console.log(Object.getPrototypeOf(man)===person) //true
console.log(man.age); //15
  •  继承对象的属性赋值问题

向一个子对象的属性赋值时,假如这个属性是从父对象继承下并且父对象中把该属性设置为不可写时,在严格模式下会报错,非严格模式下赋值不生效

var parent={
name:'parent'
}
Object.defineProperty(parent,'name',{
writable:false
})
var child=Object.create(parent)
child.name='child' //严格模式下报错,非严格模式下默认失败

向一个子对象的属性赋值时,假如这个属性是从父对象继承下来的并且父对象中设置了set描述符,则赋值时会触发set,如果未定义get,则无法获取属性值

'use strict'
var parent={
name:'parent'
}
Object.defineProperty(parent,'name',{
set(val){
console.log('父元素的set被调用了')
this._name = val
}
})
var child=Object.create(parent)
child.name='child' //会触发父对象中的set
console.log(child.name) //undefined,只有父对象的name属性描述符设置了get才能获取到值

  

  •  如何重写父对象的成员?

   直接在子对象中定义一个同名的成员即可

  •    如何实现在子对象中访问父对象的成员?

super关键字是es6新增的,它是一个指针,指向当前对象的原型,也就是父对象

     var person={
age:15,
testMethod(){
console.log('我是父类方法')
}
}
var man={
//重写父类方法
testMethod(){
console.log('我是子类方法')
super.testMethod();
}
}
Object.setPrototypeOf(man,person)
man.testMethod();

  需要注意的是,如果两个对象不是继承关系,使用super关键字会报错

  •  一句话实现jquery.extend

  jquery.extend是一个典行的对象混入,所谓对象混入,就是将n个对象(为了便于表述,直接叫做输入对象)组合成一个新对象,新对象具有各个输入对象的特征,这在软件设计模式中叫做装饰器模式,在es6以前需要自己实现,核心代码如下:

     function mixins(target,sourceArr){
sourceArr.forEach(function(source){
Object.keys(source).forEach(function(item){
target[item] = source[item]
})
})
return target
}
var obj1={
name:'123'
}
var obj2={
id:100
}
var obj3={
meth(){
console.log('haha')
}
}
var target=mixins(obj1,[obj2,obj3])
target.meth()

  上面的代码实现了一个简易版的jquery.extend的浅拷贝模式(也就是deep参数为false时的功能),如果多个对象成员同名,则后面的会覆盖前面的,该代码如果要在正式环境使用,还需要加不少的判断代码,但是在es6中一句话就可以实现mixins()函数的功能。

var target=Object.assign(obj1,obj2,obj3)

  需要注意的一点就是输入对象中使用了get修饰符,这时后会有一个转换,方法名变成了新对象的属性名,其值为get修饰符方法中的返回值

 var obj1={
name:'123'
}
var obj2={
id:100
}
var obj3={
get getMethod(){
return '123'
},
meth(){
console.log('haha')
}
}
var target=Object.assign(obj1,obj2,obj3)
console.log(target.getMethod) //target.getMethod()会报错,原因是发生了转换  

js学习日记-对象字面量的更多相关文章

  1. Js里头的对象字面量

    JavaScript 对象字面量 在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ) ...

  2. JS基础_对象字面量

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. es6对象字面量增强

    相对于ES5,ES6的对象字面量得到了很大程度的增强.这些改进我们可以输入更少的代码同时语法更易于理解.那就一起来看看对象增强的功能.对象字面量简写(Object Literal Shorthand) ...

  4. json,json对象以及js对象字面量的区别

    从定义看: json:一种数据交换格式 json对象:js的一个内置对象,拥有JSON.stringify()和JSON.parse()两个方法 js对象字面量:封闭在花括号对({})中的一个对象的零 ...

  5. js中对象字面量

    一.对象字面量语法 var person={ name:'小王', age:18, _pri:233 } 成员名称的单引号不是必须的 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误 成员名相 ...

  6. js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...

  7. js对象字面量

    在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ),JavaScript也不例外.以 ...

  8. js 对象字面量

    对象字面量的输出方式以及定义好处 1.对象字面量的输出方式有两种:传统的'.' 例如:box.name 以及数组方式,只不过用数组方式输出时,方括号里面要用引号括起来 例如:box['name'] v ...

  9. ES6入门四:对象字面量扩展与字符串模板字面量

    简洁属性与简洁方法 计算属性名与[[prototype]] super对象(暂时保留解析) 模板字面量(模板字符串) 一.简洁属性与简洁方法 ES6中为了不断优化代码,减低代码的耦合度在语法上下了很大 ...

随机推荐

  1. 5 matplotlib-绘制精美的图表

    matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中. 它的文档相当完备, ...

  2. 搞点事情,使用node搭建反向代理

    导语 最近有个需求,需要对业务管理后台的操作记录进行上报.一般这种上报需求都是又后台同学来做比较合适的.但是因为后台人力的原因.这个工作落到了我这个小前端的头上.这里记录下做这个需求踩的一些坑. 一. ...

  3. git之项目上传

    git之项目上传 需求:将项目代码上传至github 前期准备: 1.github账号注册 2.安装git环境,可以打开且使用git shell. 3.生成SSH key并与github账号绑定 步骤 ...

  4. vertex shader(4)

    Swizzling and Masking 如果你使用输入.常量.临时寄存器作为源寄存器,你可以彼此独立地swizzle .x,.y,.z,.w值.如果你使用输出.临时寄存器作为目标寄存器,你可以把. ...

  5. UGUI 自动布局的重叠BUG

    1,父级使用了verticalLayout(注意没有ContentSizeFilter),子级使用了ContentSizeFilter时,点击Apply常常发现,本来布局好的UI突然重叠到了一起,或位 ...

  6. 双 MySQL 启动、停止脚本

    5.5 启动 #!/bin/bash # author: Wang Xiaoqiang # func: Start MySQL 5.5 pid=`netstat -lnpt | awk -F '[ / ...

  7. Eclipse debug 的 drop to frame 的技巧

    前些天和同事交流调试技巧时,知道了 Eclipse debug 时有个 drop to frame 的技巧.这是我以前不知道的,自己又查了一下这个功能的含义.官方的解释是: Select the Dr ...

  8. Sunday

    字符串匹配中最简单的算法: 基本思路:wandderwonder wonder 建立256个长的next数组,记录每个字符最后一次出现的位置. 设mark1 = 0: 和 mark2 = 0:flag ...

  9. go grpc

    https://godoc.org/google.golang.org/grpc go get google.golang.org/grpc go get -a github.com/golang/p ...

  10. 201671010140. 2016-2017-2 《Java程序设计》java学习第十二周

    java学习第十章:图形程序设计       本章,介绍的是如何编写使用图形用户界面GUI的java程序.主要讲的是如何编写定义屏幕上的窗口大小和位置的程序,如何在窗口中采用多种字体显示文本,如何显示 ...