JavaScript设计模式:一、面向对象编程(第二节)

一、封装

  面向对象编程思想其中的一个特点就是封装,通俗的讲法就是把需要的功能方向在一个对象里。遗憾的是,对于JS这种解释性的弱类型语言没有经典强类型语言中那样通过class等关键字实现类的封装方法,js中都是通过一些特性模仿实现的,虽然这是个弊端,但也带来了极高的灵活性。

  我们看一个Book类是如何通过JS实现的:

 1 // 写法1
 2 var Book = function (id, name, pirce) {
 3   this.id = id
 4   this.name = name
 5   this.price = pirce
 6 }
 7 
 8 /*
 9 * 以下两种方式不可混用
10 */
11 
12 // 也可以通过在类的原型对象prototype上添加属性和方法,有两种方式
13 // 一种是一一为原型对象属性赋值
14 Book.prototype.display = function () {
15   // ...
16 }
17 
18 // 一种是将一个对象赋值给类的原型对象
19 Book.prototype = {
20   display: function () {
21     // ...
22   }
23 }

这样,我们就将所需要的方法和属性都封装在我们抽象的Book类里面,当使用功能方法时,我们不能直接使用Book类,需要用new关键字来实例化新的对象,并通过点语法来访问对象的属性或者方法。比如:

1 var book = new Book(10, '书', '50')
2 console.log(book.name)  //

从代码可以看出,我们通过this添加了属性,通过prototype添加了方法,那么这两者有什么区别?

通过this添加的属性和方法是在当前对象上添加的,然而JS是一种基于原型的prototype的语言,所以每次创建一个新对象时,通过prototype继承的方法并不是对象自身的,所以在使用这些方法时,需要通过prototype一级一级查找的来,而通过this定义的属性或者方法是该对象自身所拥有的,所以我们每次创建一个新对象时,this指向的属性和方法都会得到相应的创建。

 

二、属性与方法封装

在OOP中,既然是类,必定有私有属性,私有方法,共有属性,共有方法等这些概念,那么JS中又是如何去实现呢?

由于JS的函数作用于,声明在函数内部的变量以及方法在外界是访问不到的,通过次特性可以创建类的私有变量以及私有方法,然而在函数内部通过this创建的属性和方法,在类创建对象时,每个对象自身都拥有一份并且可以在外部访问到,因此这些属性和方法可以看作为共有的,还是Book为例:

 1 // 私有属性与私有方法,特权方法,对象共有属性和对象公有方法
 2 var Book = function (id, name, price) {
 3   // 私有属性
 4   var num = 1
 5   // 私有方法
 6   function checkId () {
 7     // ... 
 8   }
 9   // 特权方法
10   // 所谓的特权方法,是既可以被外部访问到,又可以访问类内部的私有属性与方法的方法
11   this.getName = function () {
12     // ...
13   }
14   this.getPrice = function () {
15     // ...
16   }
17   this.setName = function () {
18     // ...
19   }
20   this.setPrice = function () {
21     // ...
22   }
23   // 对象公有属性
24   this.id = id 
25   // 对象公有方法
26   this.copy = function () {
27     // ...
28   }
29 
30 }

而在OOP中,还有两个概念是:静态属性与静态方法,这两种东西都属于类所有,而不属于每一个对象,调用也只能通过类名加上点语法来使用,那么JS中如何实现呢?

其实很简单,我们可以在类定义的外面,通过点语法定义属性以及方法,这样,通过new关键字创建时,这写在类外面通过点语法添加的属性和方法是不会被执行到的,因而只能被类本身所调用,我们也就达到了模仿静态属性与方法的目的。

1 // 类静态公有属性(对象不能访问)
2 Book.isChinese = true
3 // 类静态公有方法(对象不能访问)
4 Book.getIsChinese = function () {
5   return Book.isChinese
6 }

 

posted @ 2017-05-07 16:24  吞佛童子  阅读(139)  评论(0编辑  收藏  举报