javascript面向对象程序设计——封装(by vczero)

javascript面向对象程序设计——封装
在javascript中,我们宣称是面向对象的程序设计。其实面向对象是js与生俱来的特性,每一门OOP语言都有自己的特性,我们不能为了OOP,去模仿另一门语言,把握语言的特性才是正道。我们可以通过new Object()来创建一个实例,但是不推荐这种形式,我们需要更为直观的数据封装。

一、封装你的数据特性

<span style="font-family:Courier New;"> var user = {
       name: '',
       email: ''
   };</span>

</pre><span style="font-family:'Microsoft YaHei'; font-size:12px">很简单,我们封装了一个JSON格式的对象,也称为字面量对象;User对象包含两个属性name和email。我们可以通过user.name和user.email进行赋值和取值。但是,我们发现没有一个方法可以用。那么进行改造。</span><span style="font-size:14px"><span style="font-family:'Microsoft YaHei'">二、构建你的方法</span></span><pre name="code" class="javascript"><span style="background-color: rgb(255, 255, 255);"></span><pre name="code" class="javascript"><span style="font-family:Courier New;">var user = {
       name: '',
       email: '',
       addUser: function(){
            console.log(this.name + '已经添加完成');
       }
   };</span>
我们发现,我们可以使用user.addUser函数添加一个用户了。但是我们又发现是不是每次我们创建一个对象的时候,都需要重新定义user,user1...usern。这样是不是没有了重用性和十分不优雅。js是面向对象的语言,我们继续改造。
 

三、能够构造更多的实例

<span style="background-color: rgb(255, 255, 255);"></span><pre name="code" class="javascript"><span style="font-family:Courier New;">var User = function(name, email){
         this.name = name;
         this.email = email;
         this.addUser = function(){
              console.log(this.name + '已经添加完成');
         };
    };</span>
js是函数式编程,因此function既可以是普通的函数,又可以是作为构造函数使用。如果使用了new User(),那么就是采用了构造函数的形式和特性;如果没有使用new,则是使用了全局变量window上的一个函数而已。同时,我们可以看出,var User的User进行了大写,这是采用了标准的类命名规则,建议首字母大写。User就是一个基本类,包含name和email两个属性,addUser一个方法。我们可以构建一些实例。
 
<span style="background-color: rgb(255, 255, 255);"></span><pre name="code" class="javascript"><span style="font-family:Courier New;">var user = new User('vczero', 'wlh_js@126.com');
    user.addUser();</span>
上面的类基本具有了类的基本特征了。这时,新的要求提出来了,我们能否将属性和函数都不要写在构造函数里面,太过臃肿了。其实,将addUser函数写出来时有道理的。比如:
 
<span style="background-color: rgb(255, 255, 255);"></span><pre name="code" class="javascript"><span style="font-family:Courier New;">   var user1 = new User('vczero', 'wlh_js@126.com');
   user1.addUser();
   var user2 = new User('vczero', 'wlh_js@126.com');
   user2.addUser();
   console.log(user1.addUser === user2.addUser);//false</span>

我们发现结果却是false。原因很简单,因为每一个实例都会在堆内存中创建一块存储区域,每个实例具有每个实例的特性,这两块区域是相互独立的。this指向的是本类的实例。
 

四、使用原型prototype
那样的话,不仅代码不优雅同时太浪费存储空间了。为了避免这种情况,我们不得不重新思考,有没有办法让addUser方法共享,每个实例拿着引用去调用就行。在js中,每个函数都有一个prototype(原型)属性,这个属性代表一个指针,指向的是一个对象。一般在prototype中,存放的都是共享的方法和属性。因此,我们继续改造。
<span style="background-color: rgb(255, 255, 255);"></span><pre name="code" class="javascript"><span style="font-family:Courier New;">    var User = function(name, email){
        this.name = name;
        this.email = email;
    };

    User.prototype.addUser = function(){
        console.log(this.name + '已经添加完成');
     };</span>

这样,所有的实例化的对象都引用的是同一个addUser。我们又开始思考,我们需要查询一个数据库的数据,这个时候,我们不需要在构造一个对象后然后去查询。但是,我们有需要在User命名空间下,代表是User的相关操作,这时。我们可以使用类的方法,也就是“静态方法”。
 

五、“静态方法” 或者 “类方法”

“静态方法”我打了个引号,习惯了强类型语言都习惯这种说法,比如:JAVA & C++。但是,因为js中能够随时给一个变量添加属性,那么我更愿意说是“类的方法”。

<span style="font-family:Courier New;">    var User = function(name, email){
        this.name = name;
        this.email = email;
    };

    User.prototype.addUser = function(){
        console.log(this.name + '已经添加完成');
     };

     User.findUser = function(user){
        console.log('查询到了用户' + user.name);
    };

     User.deleteUser = function(user){
        console.log('删除了用户' + user.name);
     };</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值