浅谈JavaScript的面向对象程序设计(一)

  面向对象的语言有一个标志,他们都有类的概念,通过类可以创建多个具有相同属性和方法的对象。但是JavaScript中没有类的概念,因此JavaScript与其他的面向对象语言还是有一定区别的。JavaScript把对象定义为无序属性的集合,其属性可以包含基本值、对象或者函数。对象的每个属性或者方法都有一个名字,而每个名字都映射到一个值。所有我把JavaScript的对象看成一组无序的键值对。

对象是什么

  以前曾介绍过对象的创建,建立对象最简单的方式就是建立Object对象的一个实例,再为他添加属性和方法。

1 var obj = new Object();
2 obj.name="test";
3 obj.getName=function(){
4     return this.name;
5 }
6 console.log(obj.getName());

  上面的代码第一行创建了一个对象obj,第二行给obj添加了属性name,第三行给obj添加了方法getName。通过getName方法能够获取obj属性name的值。第六行输出字符串test。

1 var obj = {};
2 obj.name="test";
3 obj.getName=function(){
4     return this.name;
5 }
6 console.log(obj.getName());

  上面的代码通过字面量创建了对象obj。其他与通过Object创建的完全一样。

对象的属性

  JavaScript有两种属性:数据属性和访问器属性。

  • 数据属性

  数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的特性。

  Configurable:表示能否通过delete关键字删除属性或者把属性修改为访问器属性。configurable默认是true。

  Enumerable:表示能否通过for-in循环,默认值为true。

  Writable:表示能够修改属性的值,默认为true。

  Value:包含这个数据的属性值。读取属性值时,从这个位置读。写入属性值的时候,把新值保存在这个位置。默认为undefined。

  对于像前面那样定义对象,他的configurable、enumerable和writable默认都是true,value是指定给它的值。

1 var obj={
2     name:"test";
3 }

  这创建的对象obj拥有一个属性,并设置value值为test。要修改默认属性必须使用Object.defineProperty()方法。这个方法接收三个参数:属性所在的对象、属性的名字和描述符。描述符对象的属性必须是configurable、enumerable、writable和value中的一个或者多个。

 1 var obj={
 2                 };
 3                 Object.defineProperty(obj,"name",{
 4                     configurable:true,
 5                     value:"hehe",
 6                     enumerable:true,
 7                     writable:false
 8                 });
 9                 obj.name="test";
10                 console.log(obj.name);//输出hehe

  这个例子创建了一个属性name,并设置wriable为false,也就是说name属性的value将无法写入。所在我在第九行修改name的值,并没有效果。name的值依然为test。

  把configurable设置为false之后,该属性就将无法通过delete删除,同时也不能通过Object.defineProperty()方法设置除writable之后的值。在严格模式下,如果调用该方法将会报错。

  当通过Object.defineProperty方法定义属性的时候,configurable、enumerable和writable特性的默认值是false。所以,最好不要通过该方法定义属性。

  • 访问器属性

  访问器属性不包含value,但是包含一对getter和setter函数。在读取访问器属性时,会调用getter函数。在写入访问器属性时,会调用setter函数。访问器属性有以下四个特性:

  Configurable:表示能否通过delete关键字删除属性或者把属性修改为访问器属性。configurable默认是true。

  Enumerable:表示能否通过for-in循环,默认值为true。

  get:在读取属性的时候调用的函数,默认值为undefined。

  set:在写入属性的值时调用的函数,默认是undefined。

  

 1 var person={"_name":"hehe","age":18}
 2                 Object.defineProperty(person,"name",{
 3                     get:function(){
 4                         return this._name;
 5                     },
 6                     set:function(str){
 7                         
 8                         if(this._name!="haha"){
 9                             this._name=str;
10                             this.age="19";
11                         }
12                     }
13                 });
14                 person.name="haha";
15                 console.log(person.name+":"+person.age);//haha:19

  上面的代码创建了一个对象person,并定义了两个属性_name和age。_name表示内部属性,一般由对象本身去访问。定义了属性name,有get和set方法。不一定要同时定义get和set方法。只有get方法,则尝试写入属性的时候报报错。只有set方法,则获取属性的时候会报错。通过Object的defineProperties能够同时定义多个属性。

 1 var obj={};
 2                 Object.defineProperties(obj,{
 3                     name:{
 4                         value:"hehe"
 5                     },
 6                     age:{
 7                         value:"18"
 8                     }
 9                 });
10                 console.log(obj.name+":"+obj.age);//hehe:18

  上面的代码,通过Object的defineProperties方法同时定义了两个属性name和age。该方法的第一个参数是对象,第二个参数是由需要定义的属性组成的对象。

  • 读取属性的特性

  JavaScript提供了Object.getOwnPropertyDescriptor方法,可以获取属性的描述符。这个方法需要两个参数:第一个参数是对象,第二个参数是描述符属性的名称。返回值是一个对象,如果是访问器属性则有configurable、enumerable、writable、get和set。如果是数据属性,这个对象有属性configurable、enumerable、writable和value。

 1 var obj={};
 2                 Object.defineProperties(obj,{
 3                     name:{
 4                         value:"hehe"
 5                     },
 6                     age:{
 7                         value:"18"
 8                     },
 9                     _sex:{
10                         value:"man"
11                     },
12                     sex:{
13                         get:function(){
14                             return this._sex;
15                         },
16                         set:function(str){
17                             this._sex=str;
18                         }
19                     }
20                 });
21                 var descriptor1=Object.getOwnPropertyDescriptor(obj,"name");
22                 var descriptor2=Object.getOwnPropertyDescriptor(obj,"sex");
23                 console.log(descriptor1.writable);//false
24                 console.log(descriptor2.get);//function
25                 console.log(obj.name+":"+obj.age+","+obj.sex);//hehe:18,man

  上面的代码,通过Object.getOwnPropertyDescriptor()方法获取属性的描述吗,分别获取了数据属性以及访问器属性。

posted on 2018-01-05 17:19  水击三千  阅读(434)  评论(0编辑  收藏  举报

导航