以下为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。
对象为无序属性的集合,其属性可以包含基本值、对象或函数。对象是一组没有特定顺序的值,对象的每个属性或方法都有一个名字,每个名字都映射到一个值,值可以是数据或函数。
目录:
1、属性类型
① 数据属性
② 访问器属性
2、定义多个属性
3、读取属性的特性
思维导图笔记:
ECMAScript 中有2种属性:数据属性和访问器属性
数据属性包含1个数据值的位置,在这个位置可以读取和写入值,数据属性有4个描述其行为的特性:[[Configurable]]、[[Enumerable]]、[[Writable]]、[[Value]]
要修改属性默认的特性,必须使用 Object.defineProperty() 方法。
1 <script> 2 //修改属性默认的特性 3 var person = {}; 4 //Object.defineProperty() 5 //接收 3 个参数 6 //第一个参数:属性所在的对象 7 //第二个参数:属性的名字 8 //第三个参数:一个描述符对象 9 Object.defineProperty(person, 'name', { 10 //configurable 11 //设置为不可设置后就不能变回去了 12 //可以多次调用Object.defineProperty()修改同一个属性,但是把configurable设置为false之后就有限制了 13 configurable : false, 14 value : 'xiaoxu' 15 }); 16 console.log( person.name ); //输出:xiaoxu 17 //configurable 设置为了 false, 所以属性是可读的但是是不可修改的,也不能够通过 delete 删除属性重新定义属性 18 person.name = "Adrian"; 19 console.log( person.name ); //输出:xiaoxu 20 delete person.name; 21 console.log( person.name ); //输出:xiaoxu 22 23 //configurable设置为不可设置后就不能变回去了 24 Object.defineProperty(person, 'name', { 25 configurable : true, 26 value : 'xiaoxu' 27 }); 28 /* 报错: 29 Uncaught TypeError: Cannot redefine property: name 30 at Function.defineProperty (<anonymous>) 31 at test2.html:24 32 */ 33 </script>
configurable、enumerable、writable 默认值都是 true。在调用Object.defineProperty()时,如果不指定,configurable、enumerable、writable的特性的默认值都是 false。
1 <script> 2 var book = { 3 //访问器属性 year 前的下划线是用来表示属性只能通过对象方法访问的记号 4 //访问器属性不包含数据值,包含一对 getter 和 setter 属性。 5 _year : 2019, 6 edition : 1 7 } 8 //访问器属性不能直接定义,必须使用 Object.defineProperty()来定义 9 Object.defineProperty(book, "year", { 10 //访问器属性 get 在读取属性时调入函数 getter,函数 getter 负责返回有效的值 11 //如果只指定 getter 意味着属性不能写 12 get : function(){ 13 return this._year; 14 }, 15 //访问器属性 set 在写入属性是调入函数 setter,函数 setter 负责传入新值并决定如何处理数据 16 //如果只指定 setter 意味着属性不能读 17 set : function( newValue ){ 18 if( newValue > 2019 ){ 19 this._year = newValue; 20 this.edition += newValue - 2019; 21 } 22 } 23 }); 24 book.year = 2020; 25 console.log( book.year ); //输出:2020 26 console.log( book.edition ); //输出:2 27 </script>
ES6 写法(参考资料:https://blog.csdn.net/zhang1339435196/article/details/101472510):
1 const book = { 2 _year: 2019, 3 edition: 1, 4 get year(){ 5 return this._year; 6 }, 7 set year(newValue){ 8 if(newValue>2019){ 9 this._year = newValue; 10 this.edition += newValue - 2019; 11 } 12 } 13 } 14 book.year = 2020; 15 console.log(book.year); //输出:2020 16 console.log(book.edition); //输出:2
利用 Object.defineProperties() 通过描述符一次定义多个属性。
1 <script> 2 var book = {}; 3 //Object.defineProperties() 4 //接收2个对象参数 5 //第一个对象参数:要添加和修改其属性的对象 6 //第二个对象参数:第二个对象的属性与第一个对象种要添加或修改的属性一一对应 7 Object.defineProperties(book, { 8 //定义2个数据属性(_year和edition),定义1个访问器属性(year) 9 _year : { 10 value : 2019 11 }, 12 edition : { 13 value : 1 14 }, 15 year : { 16 get : function(){ 17 return this._year; 18 }, 19 set : function(newValue){ 20 if( newValue>2019 ){ 21 this._year = newValue; 22 this.edition += newValue - 2019; 23 } 24 } 25 } 26 }); 27 </script>
1 <script> 2 var book = {}; 3 Object.defineProperties(book, { 4 //定义2个数据属性(_year和edition),定义1个访问器属性(year) 5 _year : { 6 value : 2019 7 }, 8 edition : { 9 value :1 10 }, 11 year : { 12 get : function(){ 13 return this._year; 14 }, 15 set : function( newValue ){ 16 if( newValue>2019 ){ 17 this._year = newValue; 18 this.edition += newValue - 2019; 19 } 20 } 21 } 22 }); 23 //Object.getOwnPropertyDescriptor() 24 //接收2个参数 25 //第一个参数:属性所在的对象 26 //第二个参数:要读取其描述符的属性名称 27 var descriptor = Object.getOwnPropertyDescriptor( book, "_year" ); 28 console.log( descriptor.value ); //输出:2019 29 console.log( descriptor.configurable ); //输出:false 30 console.log( typeof descriptor.get ); //输出:undefined 31 var descriptor = Object.getOwnPropertyDescriptor( book, "year" ); 32 console.log( descriptor.value ); //输出:undefined 33 console.log( descriptor.enumerable ); //输出:false 34 //get是一个指向getter函数的指针 35 console.log( typeof descriptor.get ); //输出:function 36 </script>