首页 > 代码库 > 面向对象的编程—封装

面向对象的编程—封装

     面向对象的程序设计,它是一种程序设计范型,也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,用以提高软件的重用性,灵活性和扩展性。

    如果我们要把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们应该怎么做呢?

1,构造函数模式

      为了解决从原型对象生成实例的问题,JS提供了构造函数的模式。所谓构造函数,就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,这个this就绑定到了实例对象中。

1 function Book(name,color){
2      this.name = name;
3      this.color = color;
4  }
5  var book1 = new Book(‘JavaScript‘,‘黄色‘);
6  var book2 = new Book(‘Css‘,‘黑色‘);
7  alert(book1.name);//输出:JavaScript
8  alert(book2.color);//输出:黑色

这时book1和book2会自动含有一个constructor属性,指向它们的构造函数。

  alert(book1.constructor == Book); //true

  alert(book2.constructor == Book); //true

Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。

 alert(book1 instanceof Book);//true

   alert(book2 instanceof Book);//true

但这种方法,存在一个浪费内存的问题。在这里增加type属性和read方法,实例如下:

 1 function Book(name,color){
 2      this.name = name;
 3      this.color = color;
 4      this.type = ‘前端‘;
 5      this.read =function(){alert(‘多读,多实践‘);}
 6  }
 7  var book1 = new Book(‘JavaScript‘,‘黄色‘);
 8  var book2 = new Book(‘Css‘,‘黑色‘);
 9  alert(book1.type);//输出:前端
10  book2.read();//输出:多读,多实践
11  alert(book2.read == book1.read);//输出:false

表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象,type属性read()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率

能不能让type属性和read()方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?回答是可以的。

2.Prototype模式

Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

例子如下:

 1 function Book(name,color){
 2      this.name = name;
 3      this.color = color;
 4  }
 5  Book.prototype.type = ‘前端‘;
 6  Book.prototype.read =function(){alert(‘多读,多实践‘);}
 7  var book1 = new Book(‘JavaScript‘,‘黄色‘);
 8  var book2 = new Book(‘Css‘,‘黑色‘);
 9  alert(book1.type);//输出:前端
10  book2.read();//输出:多读,多实践
11  alert(book2.read == book1.read);//true

这时所有实例的type属性和read()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

为了配合prototype属性,JS定义了一些方法,帮助我们使用它

2.1 isPrototypeOf()方法

   isPrototypeOf()函数用于指示对象是否存在于另一个对象的原型链中。如果存在,返回true,否则返回false

这个方法用来判断,某个proptotype对象和某个实例之间的关系。

 技术分享输出:技术分享

2.2 hasOwnProperty()方法

        hasOwnProperty判断一个对象是否有名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。 它用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。

 

1  alert(book1.hasOwnProperty(‘name‘));输出:true——这里要注意
2  alert(book1.hasOwnProperty(‘type‘));输出:false——这里要注意

2.3 in运算符

in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。

  alert("name" in book1); // true

  alert("type" in book1); // true

in运算符还可以用来遍历某个对象的所有属性。

  for(var prop in book1) { alert("book1["+prop+"]="+book1[prop]); }

 

面向对象的编程—封装