属性名表达式定义一个对象的属性有两种方式1.直接使用标识符作为属性名obj.name2.使用表达式作为属性nameobj['a'+'b']=10letobj={}obj.name='MonkeyKing'//孙悟空obj['a'+'b']=10//10console.log(obj);//{name:'孙悟空',ab:10}在es5中,字面量定义对象只能使用一种方法varobj2={name:'Orient',age:10}es6允许使用表达式属性名,表达式放在方括号中。butletkey='address'letobj3={name:'Unbeaten',[key]:'Wuhan',['a'+'ge']:100}console.log(obj3);//{name:'Unbeaten',address:'Wuhan',age:100}console.log(obj3.address);//武汉console.log(obj3[key]);//武汉表情也可以定义方法名letobj4={['f'+'n'](){console.log('hello');},fn2:function(){console.log('word')}}obj4.fn()//helloobj4.fn2()//word注意:解构和属性名表达式不能同时使用//报错reportletfan='name'letion={[fan]}如果属性名表达式是对象,则将其转换为字符串[objectobject]leto={a:1}leto2={b:2}letobj5={[o]:'东方无敌',[o2]:'西方无敌'}console.log(obj5);//{[objectObject]:'西秋白'}由于属性名表达式全部转为[objectObject],键名相同的会被覆盖,所以只覆盖最后的{[objectObject]:'西秋白'在这里输出'}name属性函数name属性返回函数名,对象方法也是一个函数,所以还有name属性letn={sayHi(){console.log('hello');}}console.log(n.sayHi。姓名);//sayHi如果对象方法的方法使用了存储函数的值函数:getter或setter,那么属性的属性在描述对象的get和set上,get和setlet需要为false在方法名之前n2={getfn(){},setfn(x){}}letdesc=Object.getOwnPropertyDescriptor(n2,'fn')console.log(desc.get.name);//获取fnconsole.log(desc.set.name);//设置fnconsole.log(n2.fn.name);//ErrorCannotreadpropertiesofundefined(reading'name')如果对象的方法是Symbol值,name属性返回Symbol值的描述letkey1=Symbol('desc')letkey2=Symbol()让kobj={[key1](){},[key2](){}}console.log(kobj[key1].name);//[desc]console.log(kobj[key2].name);//""key1有描述,返回描述[desc];key2没有值,返回一个空的属性enumerability,可遍历对象的每个属性都有一个描述对象,用于控制属性的行为,获取属性描述对象方法:Object.getOwnPropertyDescriptor()letd={a:123}console.log(Object.getOwnPropertyDescriptor(d,'a'));//{value:123,writable:true,enumerable:true,configurable:true}项valueenumerabletrue是可枚举的,false是不可枚举的configurabletrue这个特性可以删除也可以修改,false不可写true可以修改,false只可读注意在“普通方式”创建属性时,默认都是true以下四种操作会被忽略enumerable为false属性1、for...in循环:只遍历对象自身和继承的可枚举属性2、Object.keys():返回对象自身所有可枚举属性的键名3、JSON。stringify():只序列化对象本身的可枚举属性4.Object.assign():忽略enumerable为false的属性,只复制对象本身的可枚举属性其中,for...in会返回继承的属性,其他的会忽略继承的属性。如果枚举属性为false,这四种方法在遍历时都会忽略为false的属性。对象遍历方法说明for...in遍历对象本身和继承的可枚举属性(不包括Symbol)Object.keys返回一个数组,该数组返回对象本身所有可枚举属性(不包括继承属性和Symbol属性)的数组Object.values()数组,包含对象键值的数组(不包括继承属性和Symbol属性)Object.entries()返回数组,包含对象键名和键值的数组(不包括继承属性和Symbol属性)Object.getOwnPropertyNames返回一个数组,包含对象本身的所有(包括不可枚举的)属性(不包括Symbol属性)Object.getOwnPropertySymbols返回一个数组,只包含对象本身所有Symbol属性的键名数组,包括对象本身(不包括Inheritance)所有键名,(包括Symbol、string、和不可枚举的属性)下面是这些遍历方法的演示定义对象lets=Symbol('sym')//Symboltypeletf={a:1,b:2,c:3,d:4,e:5,[s]:6}for...infor(kinf){//键名console.log(k);//abcde//属性控制台。日志(f[k]);//12345}Object.keys返回对象键名数组console.log(Object.keys(f));//['a','b','c','d','e']Object.keys(f).forEach(el=>console.log(el))//abcdeObject.values返回对象键值数组console.log(Object.values(f));//[1,2,3,4,5]Object.values(f).forEach(el=>console.log(el))//12345Object.entries返回对象键名和键值数组控制台.log(对象.条目(f));//[['a',[1]],['b',[2]],['c',[3]],['d',[4]],['a',[5]]]Object.entries(f).forEach(el=>console.log(el))//['a',[1]]['b',[2]]['c',[3]]['d',[4]]['a',[5]]Object.getOwnPropertyNamesconsole.log(Object.getOwnPropertyNames(f));//['a','b','c','d','e']Object.getOwnPropertySymbolsconsole.log(Object.getOwnPropertySymbols(f));//[Symbol(sym)]Reflect.ownKeysconsole.log(Reflect.ownKeys(f));//['a','b','c','d','e',Symbol(sym)]注意:Symbol不可枚举letdesc2=Object.getOwnPropertyDescriptor(f,s)console.log(desc2);//{value:6,writable:true,enumerable:true,configurable:true}//这里返回的是enumerable:true,返回的是对象的枚举属性,不是Symbol//Symbol是不可枚举的,所以键遍历中没有Symbol解构赋值和剩余的运算符解构:可以直接根据对象的键名获取键值,非常方便let{a,b,...z}={a:1,b:2,c:3,d:4,e:5}console.log(a,b,z);//12{c:3,d:4,e:5}letinfo={id:1,name:'东方无敌'}let{id,name}=infoconsole.log(id,name);//1'东方无敌'//重命名let{id,name:user}=infoconsoleonsole.log(id,用户);//1'东方无敌'解构赋值可以单层嵌套letinfos={vals:1,users:{names:'东方无敌'}}let{vals,users:{names}}=infosconsole.日志(名称);//东方无敌多层嵌套letinfo2={val:1,user:{id2:100,name2:'东方无敌',address:{city:'Wuhan',district:'世界城广场'}}}let{val,user:{id2,name2,address:{city,district}}}=info2console.log(val,id2,name2,city,district);//1100'东方无敌''武汉''世界城广场'对象其余算子可以将字符串转成键值对对象,键名默认从0开始,顺序排列console.log({...'世界'});//{0:'w',1:'o',2:'r',3:'l',4:'d'}对象的rest运算符等同于Object.assign(),但是这些两个不相等letr={id:1,name:'Orient',text:'Undefeated'}letres={...r}letres2=Object.assign({},r)console.log(res);//{id:1,name:'Oriental',text:'Undefeated'}console.log(res2);//{id:1,name:'Oriental'',text:'Undefeated'}console.log(res==res2);//false剩余运算符拼接,重复键名会被覆盖letr2={a:1,b:2,c:3,d:4}letr3={c:6,d:7,e:8,f:9}console.log({...r2,...r3});//{a:1,b:2,c:6,d:7,e:8,f:9}函数对象内部的对象不仅可以定义字符串、数字、数组等常用数据类型,还可以定义函数。对象中函数的行为与普通函数的行为相同。普通函数和箭头函数都可以定义在对象中。函数的调用方法:对象名.methodletfn={title:'东方无敌',sayHi(){console.log('hello')},getSum(x){returnx%2==0?true:false},getNum:s=(x)=>x+1}console.log(fn.title);//东方不败fn.sayHi()//helloconsole.log(fn.getSum(3));//falseconsole.log(fn.getSum(4));//trueconsole.log(fn.getNum(1));//2Object.keys()可以遍历对象键名数组,对象中的函数会返回函数名Object.keys(fn).forEach(el=>console.log(el))//titlesayHigetSumgetNum对象内部函数this对象指向问题与普通函数对象内部函数有点不同:普通函数:this指向对象本身,也就是当前对象中的所有属性和方法箭头函数:this指向window,因为该对象不构成单独的作用域,箭头函数定义的作用域是全局作用域。window.val='西求败'letfn2={name:'艺术概论',inThis(){console.log(this.val)},//普通函数inThis2(){console.log(this.name)控制台日志(这个);},//正常函数inThis3:t=()=>{console.log(this.val)console.log(this);constt2=()=>{console.log(this);}}//箭头函数}//普通函数functiongetThis2(){console.log(this.val);}getThis2()//西求败fn2.inThis()//undefinedfn2.inThis2()//艺术概论//{name:'艺术概论',inThis:?,inThis2:?}fn2.inThis3()//西求败//Window{window:Window,self:Window,document:document,name:'',location:Location,...}这里在对象中定义了普通函数和箭头函数。inThis()的输出是undefined,因为对象中没有val属性,没有找到this.val,而undefinedinThis2()的输出是undefined,this.name是当前对象中的名字,对象中的普通函数this指向当前对象inThis3()是一个箭头函数,输出是西式的,对象中的箭头函数this指向windowcase源码:https://gitee.com/wang_fan_w/es6-science-institute如果您觉得本文对您有帮助,请点亮star
