javascript面向对象(一)

时间:2022-10-24 17:21:44
  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); //会返回代码