一、对象字面量语法

var person={
name:'小王',
age:18,
_pri:233
} 

  

  • 成员名称的单引号不是必须的
  • 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误
  • 成员名相同会发生什么?

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

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

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

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

原文链接:https://www.cnblogs.com/94pm/p/9179231.html

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(person);
//添加成员无效,非严格模式下什么都不会发生,严格模式下会报错
person.bankAccount='中国农业银行'
//依然可以删除成员,证明了preventExtensions方法只能阻止添加方法
delete person.age;
console.log(person.age) //undefined,表明删除成功了

  

  • 我不想让别人添加、删除成员

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

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

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

四、其它技巧

  • 实现继承

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. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

  2. javascript中对象字面量与数组字面量

    第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例呢?下面我介绍两种方法: 第一:构造函数法. ...

  3. javascript中的对象字面量为啥这么酷

    原文链接 : Why object literals in JavaScript are cool 原文作者 : Dmitri Pavlutin 译者 : neal1991 个人主页:http://n ...

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

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

  5. js学习日记-对象字面量

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

  6. Js里头的对象字面量

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

  7. js对象字面量

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

  8. JS基础_对象字面量

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

  9. Java常量,变量,对象(字面量)在JVM内存中的存储位置

    Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540  收藏 更多 分类专栏: JAVA jvm   苦苦研究了快 ...

随机推荐

  1. REST API的使用

    需求描述 GET: http://localhost:8080/MyWebsite/user/ Header: Content-Type = application/json Body: 空 Resp ...

  2. 4-9 Panadas与sklearn结合实例

      1.显示百分比的柱状图 In [1]: import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplo ...

  3. fiddler---Fiddler接口测试

    前面介绍了Fiddler一些简单的使用功能,Fiddler不仅可以抓包也可以做接口工具使用,在没有接口文档的时候我们也可以通过Fiddler查看接口具体有哪些内容 Fiddler发送请求 在Fiddl ...

  4. git笔录

    [一]git介绍 初始的项目版本管理可以在本地赋值备份之前版本代码,项目较小时还可以,但项目较大时,这种方法显得有点捉襟见肘 ... ... 后期也出现了很多版本管理工具,例如svn.vcs.vss等 ...

  5. IEEE754 浮点数

    IEEE754 浮点数 1.阅读IEEE754浮点数 A,阶码是用移码表示的,这里会有一个127的偏移量,它的127相当于0,小于127时为负,大于127时为正,比如:10000001表示指数为129 ...

  6. Html学习之十(CSS选择器的使用--伪类选择器)

    伪类选择器 一.基于a标签. 1.:hover 选择鼠标滑过的超链接元素 2.:active 选择鼠标单击中的超链接元素 3.:link 选择未被访问的超链接元素 4.:visited 选择已经被访问 ...

  7. Session中短信验证码设置有效时间

    Session中短信验证码设置有效时间 package com.mozq.boot.kuayu01.controller; import org.springframework.web.bind.an ...

  8. MySQL学习笔记6——备份与恢复

    备份与恢复 备份与恢复 数据库-->sql:备份 sql-->数据库:恢复 1.数据库导出SQL脚本 >mysqldump -u用户名 -p密码 数据库名>生成的脚本文件路径 ...

  9. JDOJ3007 铺地板I

    JDOJ3007 铺地板I https://neooj.com/oldoj/problem.php?id=3007 题目描述 有一个大小是 2 x N(1 <= N <= 105)的网格, ...

  10. USACO19JAN Gold题解

    噩梦的回忆.. 上周日在机房打的模拟赛,结果十分惨烈,就最后一题yy出了正解结果玄学的只拿了80 考试结果:0+0+80=80 订正时对着T3打了2hours结果还是90 订正结果:100+100+9 ...