面向对象的程序设计-理解对象
理解对象
创建自定义对象的最简单方式就是创建一个Object的实例,然后再为它添加属性和方法
1 var person = new Object(); 2 person.name = "Nicholas"; 3 person.age = 29; 4 person.job = "SoftWare Engineer"; 5 person.sayName = function(){ 6 alert(this.name); 7 };
创建对象的首选模式是对象字面量方式
1 var person = { 2 name: "Nicholas", 3 age: 29, 4 job: "SoftWare Engineer", 5 sayName: function(){ 6 alert(this.name); 7 } 8 };
属性类型
内部属性无法直接访问,ECMAScript5把它们放在两对方括号中,分为数据属性和访问器属性
1、数据属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的特性
[[Configurable]]:表示能否通过delete输出属性从而定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为true
[[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
[[Writable]]:表示能否通过修改属性的值,默认值为true
[[Value]]:包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置
要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty()这个方法.这个方法接受三个参数:属性所在的对象、属性的名字和一个描述符对象
1 var person = {}; 2 Object.defineProperty(person,"name",{ 3 writable: false,//设置为不可修改属性的值 4 value: "Nicholas" 5 }); 6 7 console.log(person.name); // " Nicholas" 8 person.name = "Oreg"; 9 console.log(person.name); // " Nicholas"
把donfigurable设置为false,表示不能从对象中删除属性。一旦把属性定义为不可配置的,就不能再把它变回可配置的了。此时,在调用Object.defineProperty()方法修改处writable之外的特性,都会导致错误
1 var person = {}; 2 Object.defineProperty(person,"name",{ 3 configurable: false, 4 value: "Nicholas" 5 }); 6 7 //抛出错误 8 Object.defineProperty(person,"name",{ 9 configurable: true, 10 value:"Nicholas" 11 });
在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable和writable特性的默认值都是false
2、访问器属性
访问器属性不包含属性值;他们包含一对儿getter和setter函数,在读取访问器属性时,会调用setter函数,这个函数负责返回有效的值,在写入访问器属性时,会调用getter函数,并传入新值,这个函数决定如何处理数据。访问器属性有如下4个特性
[[Configurable]]:表示能否通过delete输出属性从而定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为true
[[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
[[Get]]:在读取属性时调用的函数。默认值为undefined
[[Set]]:在写入属性时调用的函数。默认值为undefined
访问器属性不能直接定义,必须使用Object.defineProperty()来定义。
1 var book = { 2 _year: 2004, 3 edition: 1 4 }; 5 6 Object.defineProperty(book,"year",{ 7 get: function(){ 8 return this._year; 9 }, 10 set: function(newValue){ 11 if(newValue > 2004){ 12 this._year = newValue; 13 this.edition += newValue - 2004; 14 } 15 } 16 }); 17 18 book.year = 2005; 19 console.log(book.edition); //2
这是使用访问器的常见方式,即设置一个属性的值会导致其他属性发生变化,year前面的下划线是一种
常用的记号,用于表示只能通过对象方法访问的属性
不一定非要同时指定getter和setter。只指定getter意味着属性是不能写的,只指定setter函数的属性
也不能读
两个非标准的方法:__defineGetter__()和__defineSetter__()
1 var book = { 2 _year: 2004, 3 edition: 1 4 }; 5 6 book.__defineGetter__("year",function(){ 7 return this._year; 8 }); 9 book.__defineSetter__("yeat",function(newValue){ 10 if(newValue > 2004){ 11 this._year = newValue; 12 this.edition += newValue - 2004; 13 } 14 }); 15 16 book.year = 2006; 17 console.log(book.year);
定义多个属性
Object.defineProperties()方法。利用这个方法可以通过描述符一次定义多个属性。
1 var book = {}; 2 3 Object.defineProperties(book,{ 4 _year: { 5 value: 2004 6 }, 7 edition: { 8 value: 1 9 }, 10 year: { 11 get: function(){ 12 return this._year; 13 }, 14 set: function(newValue){ 15 if(newValue > 2004){ 16 this._year = newValue; 17 this.edition += newValue - 2004; 18 } 19 } 20 } 21 });
读取属性的特性
Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符
1 Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符 2 3 var book = {}; 4 5 Object.defineProperties(book,{ 6 _year: { 7 value: 2004 8 }, 9 edition: { 10 value: 1 11 }, 12 year: { 13 get: function(){ 14 return this._year; 15 }, 16 set: function(newValue){ 17 if(newValue > 2004){ 18 this._year = newValue; 19 this.edition += newValue - 2004; 20 } 21 } 22 } 23 }); 24 25 var descriptor = Object.getOwnPropertyDescriptor(book,"_year"); 26 console.log(descriptor.value); //2004 27 console.log(descriptor.configurable); //false 28 console.log(typeof descriptor.get); //"underfined" 29 30 var descriptor = Object.getOwnPropertyDescriptor(book,"year"); 31 console.log(descriptor.value); //underfined 32 console.log(descriptor.enumerable); //false 33 console.log(typeof descriptor.get); //"function"