javascript面向对象(一)
1 // 六:面向对象的程序设计 2 // 什么是对象: “无序属性的集合,他们可以包含基本值,对象或者函数”,严格来说,就相当于一组没有特定顺序的值,每个对象和方法都有一个特定的名字, 3 // 每个名字都映射一个值。 4 // 每个对象都是一个基于引用类型创建。 5 6 // 一、属性类型(特性):数据属性和访问其属性 这些属性的特性是给jsvascript引擎用的,因此不是直接访问它们 7 // 1.数据属性 8 // [[Configurabale]]:表明能否delete删除属性从而重新定义属性;能否修改属性的特性或者能否把属性修改为访问 9 // 其属性: 10 // [[Enumerable]]: 表示能都通过 for-in进行迭代 11 // [[Writeble]]:能否修改属性的值 12 // [[Value]]: 保存属性的值 13 14 // 要想修改上述属性的特性,必须使用ECMAScript 5规定的 Object.defineProperty() 方法;这个方法接受三个参数 15 // ①属性所在对象 ②属性的名称 ③一个描述符的对象,描述符特性必须以上四个中的一个或多个 16 17 var person = {}; 18 Object.defineProperty(person,"name",{ 19 //configurable:false, 20 writable:false, 21 value:"zhd" 22 }); 23 person.name = 'qi'; //由于writable的标记,此时是违法的 浏览器会忽略该句的执行,严格模式下报错 24 //delete person.name; //由于 configurable 该操作同样违法 25 alert(person.name); // zhd 26 27 // 并且一旦标记configurable = false,无法通过Object.defineProperty()将configurable 更改为false, 28 // 一旦定义成不可配置类型的,就无法在将其改为可配置类型,此时在调用Object.defineProperty()修改除writable 29 // 之外的特性,都会出错。 30 // 也就是说 可以多次调用Object.defineProperty()修改同一属性,但是在configurable设置为flase,时,就会有 31 // 限制 32 //在调用Object.defineProperty()方法,如果不指定configurable,writable,Enumerable,则默认为false 33 //(字面量创建对象时,默认为true) 34 35 //2.访问器属性(getter/setter) 36 // [[Configurabale]]:表明能否delete删除属性从而重新定义属性;能否修改属性的特性或者能否把属性修改为访问器属性: 37 //直接在对象上定义的属性,这么属性值默认为true 38 // [[Enumerable]]: 表示能都通过 for-in进行迭代 直接在对象上定义的属性,这么属性值默认为true 39 // [[Get]]:读取属性 值 默认为undefined 40 // [[Set]]: 写入属性 值 默认为undefined 41 //访问器同样也只能使用Object.defineProperty() 来设定 42 var book = { 43 _year:2016, //① 44 edition:1 45 }; 46 Object.defineProperty(book,"year",{ 47 get:function() { 48 return this._year; //② 49 }, 50 set:function(newValue) { 51 if(newValue > 2016){ 52 this._year = newValue; //③ 53 //console.log(newVlaue); 54 this.edition += newValue - 2016; 55 } 56 } 57 }); 58 book.year = 2017; 59 //book._year = 2016; //浏览器会直接忽略 60 alert(book.year); // 61 alert(book.edition); //2 意味着 设置一个属性的同时,也可以改变其他属性的值 62 63 //千万不要忘记 ②②③处的"_",忘记后就出现 Maximum call stack size exceeded 错误。 64 //"_"用于表示只能通过对象方法访问的属性 _year为数据属性 year为访问器属性 65 //直接访问 带"_"的属性, 浏览器就会直接忽略掉 66 //与java 私有变量提供访问器类型,不过是将get/set方法变为了对year属性的访问来代替对 _year的访问 67 //java: 68 //int getYear(){ return _year;} person.getYear() ==> person.year; 69 //void setYear(int value) {this._year = value;} person.setYear(2) ==> person.year = 2; 70 //不一定非要指定get/set方法:只有get时,属性只读;只有set时,属性只能写入 71 //还有两个旧方法: 72 book.__defineGetter__("year",function () { 73 return this._year; 74 }); 75 book.__defineSetter__("year",function(newValue){ 76 if(newValue > 2016){ 77 this._year = newValue; 78 this.edition += newValue - 2016; 79 } 80 }); 81 82 //定义多个属性 (在函数体内也可以直接地定义 get/set) 83 var book = {}; 84 Object.defineProperties(book,{ 85 _year:{ 86 value:2016 87 }, 88 edition:{ 89 value:1 90 }, 91 year:{ 92 get:function(){ 93 return this._year; 94 }, 95 set:function(newValue){ 96 if(newValue > 2016){ 97 this._year = newValue; 98 this.edition += newValue - 2016; 99 } 100 } 101 } 102 }); 103 104 105 //读取对象属性的特性 返回值时一个对象 106 //如果是数据属性,则有configurable,enumerable,writable和value 107 //如果是访问器属性则有 configurable,enumerable,set和get 108 //访问数据属性 109 var descriptor = Object.getOwnPropertyDescriptor(book,"_year"); 110 alert(descriptor.value); //2016 111 alert(descriptor.configurable); //false 112 //alert(type descriptor.get); //"undefined" 113 //访问访问器属性 114 var descriptor = Object.getOwnPropertyDescriptor(book,"year"); 115 alert(descriptor.value); //undefined 116 alert(descriptor.enumerable); //false 117 alert(typeof descriptor.get); //"function" 118 alert(descriptor.get); //会返回代码