javascript 中的面向对象实现 如何封装

面向对象的手法来封装javascript ,javascript是没有类的概念的.

所以今天谈到的封装,其实就是用javascript的函数来实现的.

1

2

3

4

var People{

    name:’一介布衣’,

    age:’30'

};

 

这就是javascript中的一个对象,里面封装了2个属性.

 

实例化一个对象的实例 people

1

2

var people=new People();

console.log(people.name,people.age);  //一介布衣,30

 

如果我们需要在函数里返回一个对象,如下代码:

1

2

3

4

5

6

function CreatePeople(){

    return {

        name:’一介布衣’,

        age:’30'

    };

}

 

在代码中需要创建一个人的时候,我们需要调用 CreatePeople 即可,但是有一个问题,就是我们得到的都是同一个人 一介布衣,30岁.看来需要我们改造一个函数.

1

2

3

4

5

6

function CreatePeople(name,age){

    return {

        name:name,

        age:age

    }

}

 

这看上去貌似好多了.我们实例化2个对象.

1

2

var p1=new CreatePeople(‘张三’,19);

var p2=new CreatePeople(‘李四’,25);

 

我们知道javascript从object 到其他全局类都有一个prototype对象指向原型链.

但是,p1,p2 俩个对象貌似没有一点关系,虽然被同一个函数创建,但是CreatePeople 每次返回一个全新的对象,看似 p1,p2关系不大.

如果你接触过面向对象语言的编程,这时应该想到了构造函数,但是上面的 CreatePeople 函数怎么看都不是一个构造函数,我们也可以用javascript的函数来生成一个构造函数.

1

2

3

4

function CreatePeople(name,age){

    this.name=name;

    this.age=age;

}

 

this 和其他语言一样,也是一个指向实例的指针变量.

当用此构造函数创建对象的时候,this就指向新创建的对象,有一点需要记住,this取决调用函数作用域,而不是使用函数的作用域.

 

这样封装一下构造函数,生成的对象就比上面看上去顺眼多了.

2个属性指向了this实例指针,我们再来一个方法,去获取属性(也可以理解为私有变量)

1

2

3

4

5

6

7

function CreatePeople(name,age){

    this.name=name;

    this.age=age;

    this.getName=function(){

        return this.name;

    }

}

 

getName 方法很简单,就是返回对象中的 name 属性值.

实例化2个对象

1

2

var p1=new CreatePeople('张三',20);

var p2=new CreatePeople('李四',21);

1

2

console.log(p1.getName()) //张三

console.log(p2.getName()) //李四

这时感觉封装的高大上的感觉,其实我们没有发现,CreatePeople 构造函数中的 getName 函数干的活很简单,但是每次都在实例上创建一个这样的函数确实有点浪费内存了,我们看下面的代码.

1

console.log(p1.getName==p2.getName);  //false

返回false ,告诉我们 p1,p2 中的 getName 不是指向内存中的一个地址,我们为了节省内存,如何让CreatePeople 构建出来的对象,多有 getName 方法指向一个指针地址? 对,Object 的原型链上.

我们把这个方法定义在构造函数的原型链上,这样构造的新对象都会继承原型链上的这个方法,(具体的javascript中的继承我们单独开一篇博文来讨论)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function CreatePeople(name,age){

    this.name=name;

    this.age=age;

}

 

CreatePeople.prototype.getName=function(){

    return this.name;

}

 

 

var p1=new CreatePeople('张三',20);

var p2=new CreatePeople('李四',21);

 

console.log(p1.getName==p2.getName);  //true

 

可以看到p1 和 p2 对象都继承来自 CreatePeople 原型上的 getName 方法,而且所有对象的此方法指针都指向了一个地址.

这样,我们封装的目的就达到了.

posted @ 2015-05-12 18:53  papahot  阅读(256)  评论(0编辑  收藏  举报