js中对象字面量
一、对象字面量语法
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创建时,省略的描述符会拥有默认值,布尔值的字段的默认值都是false。value,get和set字段的默认值为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中对象字面量的更多相关文章
- javascript中对象字面量的理解
		
javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...
 - javascript中对象字面量与数组字面量
		
第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例呢?下面我介绍两种方法: 第一:构造函数法. ...
 - javascript中的对象字面量为啥这么酷
		
原文链接 : Why object literals in JavaScript are cool 原文作者 : Dmitri Pavlutin 译者 : neal1991 个人主页:http://n ...
 - json,json对象以及js对象字面量的区别
		
从定义看: json:一种数据交换格式 json对象:js的一个内置对象,拥有JSON.stringify()和JSON.parse()两个方法 js对象字面量:封闭在花括号对({})中的一个对象的零 ...
 - js学习日记-对象字面量
		
一.对象字面量语法 var person={ name:'小王', age:18, _pri:233 } 成员名称的单引号不是必须的 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误 成员名相 ...
 - Js里头的对象字面量
		
JavaScript 对象字面量 在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ) ...
 - js对象字面量
		
在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ),JavaScript也不例外.以 ...
 - JS基础_对象字面量
		
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
 - Java常量,变量,对象(字面量)在JVM内存中的存储位置
		
Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540 收藏 更多 分类专栏: JAVA jvm 苦苦研究了快 ...
 
随机推荐
- UIAlertView和UIAlertController
			
UIAlertView 随着苹果上次iOS 5的发布,对话框视图样式出现在了我们面前,直到现在它都没有发生过很大的变化.下面的代码片段展示了如何初始化和显示一个带有“取消”和“好的”按钮的对话框视图. ...
 - 解决iOS地图持续定位耗电问题
			
地图位置刷新的代理didUpdateLocations会持续调用,手机非常耗电 但是在实际开发中,有一些APP确实需要用到持续定位的功能,比如:运动类, 导航类, 天气类等等 如何进行持续定位呢?保证 ...
 - 030.[转] sql事务特性
			
sql事务特性简介 pphh发布于2018年10月5日 Sql事务有原子性.一致性.隔离性.持久性四个基本特性,要实现完全的ACID事务,是以牺牲事务的吞吐性能作为代价的.在有些应用场景中,通过分析业 ...
 - Linux PXE + Kickstart 自动装机
			
大规模装机时,使用无人值守装机便可大大简便人工操作,提高效率. PXE 网络安装 配置双网卡 这里ens33为nat网络,ens37为仅主机网络,配置ens37 [root@localhost ~]# ...
 - nginx 的 proxy_cache 缓存配置
			
开头:某个项目涉及到 视频切片下载到本地,然后提供服务给客户端.一个视频有多个文件,存储在本地路径下.当客户端请求的视频在本地没有就会回源, 回源拿到的视频文件再返回给客户端,同时在本地缓存一份,提供 ...
 - ts开发环境搭建
			
ts为typescript的缩写,是javascript的超集. npm源改为国内 由于 Node 的官方模块仓库网速太慢,模块仓库需要切换到阿里的源. npm config set registry ...
 - SpringCloud学习笔记(八、SpringCloud Bus)
			
目录: 什么是bus消息总栈 如何使用bus消息总栈 什么是bus消息总栈 SpringCloud Bus使用轻量的消息代理连接分布式系统的各个节点,可以用于系统状态变更时的广播(如配置变更)或其它管 ...
 - c# WF 第10节 textbox 控件
			
本节内容: 1:textbox 在哪里 2:textbox 的属性 1:textbox 在哪里 2:textbox 的属性 3:实例 实现如下: 步骤1 :7个label 2个textbox 步骤2 ...
 - day54_9_18视图层某内部原理(fbv和cbv)与模板层
			
一.render内部原理. 在render中往往需要返回三个参数,request,模板和一些键值对. 键值对中存储的是需要对模板渲染的值. 如果手动实现可以如下: from django.templa ...
 - ORM对象关系映射:
			
django配置orm: django使用mysql数据库: 首先cmd创建库 settings配置mysql数据库: DATABASES = { 'default': { 'ENGINE': 'dj ...