一、对象的属性、方法简写
1.属性的简写
var name = '赵' ;
var obj = {
name: name
}
console. log ( obj) ;
var name = '赵' ;
var stu = {
name
}
console. log ( stu) ;
2.方法的简写
let a = 10 ;
let b = 20 ;
let stu = {
sleep : function ( ) {
} ,
eat ( ) {
return {
a, b
}
}
}
二、setter、getter访问器
对象里面的getter、setter访问器,这两个访问器是操作属性的,至于属性的可读可写,只读和getter、setter访问器有关。 getter访问器获取值,setter访问器是设置值 对象中简写的方法不能当作构造函数来使用,会报错
1.针对属性获取或设置
let person= {
init ( ) {
} ,
get name ( ) {
console. log ( "获取name属性" ) ;
return this . _name;
} ,
set name ( n ) {
console. log ( "设置name属性" ) ;
this . _name= n;
}
}
console. log ( person) ;
person. name= "张三" ;
console. log ( person. name) ;
new person. init ( ) ;
2.对象获取值的方法二
对象点属性 对象[key](不只可以取值,还可以检测属性是否存在) es6允许对象的属性可以是变量,变量添加[]----字面量解析
let key= "name" ;
let obj1= {
[ key] : '张三'
}
console. log ( obj1) ;
console. log ( obj1[ key] ) ;
三、属性名表达式
对象的常规属性定义
let o = { } ;
o. age = 18 ;
o[ 'sex' ] = '男' ;
console. log ( o) ;
对象的属性可以以接入字面变量的方式定义。也就是对象的属性可以是变量,通过解析变量产生对象的属性。
let person = "name" ;
let per = "eat" ;
let list = {
[ person] : '' ,
[ per] ( ) {
console. log ( '执行函数' ) ;
}
}
console. log ( list) ;
console. log ( list[ per] ( ) ) ;
console. log ( list[ per] . name) ;
四、方法的 name 属性
函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。
获取get、set访问器的name属性。
let a = {
set age ( n ) {
this . _age = n;
} ,
get age ( ) {
return _age;
}
}
console. log ( a. age. name) ;
会报错,get、set访问器的name属性不能直接获取。 那么,怎样获取呢? 如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面,而是该方法的属性的描述对象的get和set属性上面,返回值是方法名前加上get和set。
let descript = Object. getOwnPropertyDescriptor ( a, 'age' ) ;
console. log ( descript) ;
console. log ( descript. set. name) ;
console. log ( descript. get. name) ;
五、使用原生js设置getter、setter访问器
设置多个属性
设置get、set访问器不能配置value、writeable属性
let obj= {
get sex ( ) { return this . _sex; } ,
set sex ( n ) { this . _sex= n; }
}
Object. defineProperties ( obj, {
name: {
enumerable: true ,
configurable: true ,
get : function ( ) {
return this . _name;
} ,
set : function ( n ) {
this . _name= n;
} ,
}
} ) ;
obj. name= "张三" ;
obj. sex= "女" ;
console. log ( obj. name) ;
console. log ( obj. sex) ;
console. log ( obj) ;
设置单个属性
let obj= {
get sex ( ) { return this . _sex; } ,
set sex ( n ) { this . _sex= n; }
}
Object. defineProperty ( obj, 'age' , {
enumerable: false ,
configurable: true ,
get : function ( ) {
return this . _age;
} ,
set : function ( n ) {
this . _age= n;
} ,
} ) ;
obj. sex= "男" ;
obj. age= 10 ;
console. log ( obj) ;
console. log ( Object. getOwnPropertyDescriptor ( obj, 'age' ) ) ;
console. log ( obj. age) ;
console. log ( obj. sex) ;
六、属性的可枚举性和遍历
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。 Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
let people = {
name: "赵佳敏" ,
age: 20
}
var desc = Object. getOwnPropertyDescriptor ( people, 'name' ) ;
console. log ( desc) ;
Object. defineProperty ( people, 'name' , {
enumerable: false
} ) ;
var desc1 = Object. getOwnPropertyDescriptor ( people, 'name' ) ;
console. log ( desc1) ;
defineProperty直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。 描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。 有四个操作会忽略enumerable为false的属性 for…in循环:只遍历对象自身的和继承的可枚举的属性。 Object.keys():返回对象自身的所有可枚举的属性的键名。 JSON.stringify():只串行化对象自身的可枚举的属性。 Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。 Object.assign()是 ES6 新增的。其中,只有for…in会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性。实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for…in操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for…in遍历到。
for ( let key in people) {
console. log ( key) ;
}
console. log ( delete people. age) ;
console. log ( people) ;
configurable----delete删除,是否可以删除对象属性,true可以删除,false不可删除 enumerable—是否可以枚举 writable----是否可写 ES6 规定,所有 Class 的原型的方法都是不可枚举的
七、属性的遍历
(1)for…in
for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。 以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。 首先遍历所有数值键,按照数值升序排列。 其次遍历所有字符串键,按照加入时间升序排列。 最后遍历所有 Symbol 键,按照加入时间升序排列。
let sw = {
name: 'zhao' ,
age: 10 ,
sex: "女" ,
[ Symbol ( 'age' ) ] ( ) {
console. log ( '独一无二的方法' ) ;
}
}
for ( let key in sw) {
console. log ( key) ;
}
console. log ( Object. keys ( sw) ) ;
console. log ( Object. getOwnPropertyNames ( sw) ) ;
console. log ( Object. getOwnPropertySymbols ( sw) ) ;
console. log ( Reflect. ownKeys ( { [ Symbol ( ) ] : 0 , b: 0 , 10 : 0 , 2 : 0 , a: 0 } ) ) ;
八、super 关键字
我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。
let person= {
name ( ) {
console. log ( "全名称" ) ;
} ,
}
let student= {
sleep ( ) {
console. log ( this ) ;
super . name ( ) ;
}
}
Object. setPrototypeOf ( student, person) ;
student. sleep ( ) ;
console. log ( student) ;
九、扩展运算符—内存引用问题
let a1= { a: 1 } ;
let { ... x} = a1;
a1. a= 2 ;
console. log ( x. a) ;
let a2= { a: { b: 1 } } ;
let { ... x1} = a2;
a2. a. b= 2 ;
console. log ( x1. a. b) ;
首先是a1复制了一份给了x,是外部空间的引用空间链断了,所以a1改变以后对x没有影响,x1.a.b为2是因为外部空间引用链断了,但是内部引用链没有变,所以输出为2