javascript 创建私有成员和静态私有成员

原创 2015年07月03日 21:23:45

私有方法和属性

在javascript中,因为没有类的概念,所以只能通过构造函数来模拟类,假设现在需要写一个手机类,这个手机需要传入一张电话号码,然后能打电话。最简单的方式是

var Phone= function(num){
  //手机号
  this.num= num;
  //打电话
  this.call = function(phone){
      console.log(this.num + "正在呼叫" + phone.num);
  }
}

var p1= new Phone("13012341234");

为了数据的正确性,我们可能还会在给num赋值的时候检查其合法性,比如

var Phone= function(num){
  if(!this.checkNum(num)){
    throw new Error("手机号非法!");
  }
  //手机号
  this.num= num;
  //打电话
  this.call = function(phone){
      console.log(this.num + "正在呼叫" + phone.num);
  }
}

//验证手机号合法性
Phone.prototype.checkNum = function(num){
  if(/^1[358]\d{9}$/.test(num)){
    return true;
  }else{
    return false;
  }
}

var p1 = new Phone("13312341234");
var p2 = new Phone("15812341234");

p1.call(p2);  //13312341234正在呼叫15812341234

这样情况会好很多,但是虽然在创建对象的时候对num进行了控制,但当这段代码给其他程序员用的时候,他可能会直接给手机赋值,比如

p1.num = "abcdefg";
p1.call(p2);

即使能在构造函数中对数据的完整性进行检验,但我们还是无法控制属性被任意修改,对于这种情况,我们可以利用闭包来将num变为私有变量,外界想访问num只能通过其get和set方法。

var Phone= function(num){
  //私有变量
  var _num;

  //特权方法
  this.setNum = function(num){
    if(!this.checkNum(num)){
      throw new Error("手机号非法!");
    }
    _num = num;
  };

  this.getNum = function(){
    return _num;
  };

  this.call = function(phone){
      console.log(_num + "正在呼叫" + phone.getNum());
  };

  //初始化
  this.setNum(num);
}

Phone.prototype.checkNum = function(num){
  if(/^1[358]\d{9}$/.test(num)){
    return true;
  }else{
    return false;
  }
}

var p1 = new Phone("13312341234");
var p2 = new Phone("15812341234");

p1.call(p2);  //13312341234正在呼叫15812341234

如num一样的属性或方法是用var关键字声明的,而不是this,这就代表其只能在函数内部使用,因此形成了一个私有属性,私有方法也是类似,在构造函数里直接声明一个函数即是私有方法。私有方法不能被外部直接访问,但又能通过像setNum和getNum这样的函数通过闭包特点访问,这种能访问私有属性的公有方法称为特权方法。
然而这种方式创建对象也有弊端,call函数调用了私有属性num,所以它只能放在构造函数里面,而特权方法太多往往会占用过多内存,因为每生成一个新的对象实例都将为每个私有方法和特权方法生成一个副本,这也比最开始的方式耗费更多内存。

静态方法和属性

静态成员是和类有关的,而不是和实例相关联,也就是说静态成员直接通过类访问,所有实例共享一份静态成员,实现共有静态方法很简单,只需通过将其赋值给构造函数即可,如Phone.count = 5;但私有静态成员是不能被外部直接访问的,这就又需要用到闭包:

var Phone= (function(){

  //静态私有属性
  var count = 0;

  return function(num){
    //私有变量
    var _num;

    //特权方法
    this.setNum = function(num){
      if(!this.checkNum(num)){
        throw new Error("手机号非法!");
      }
      _num = num;
    };

    this.getNum = function(){
      return _num;
    };

    this.call = function(phone){
      console.log(_num + "正在呼叫" + phone.getNum());
    };

    //超过50个手机不予创建
    count++;
    if(count > 50){
      throw new Error("只能创建50个手机!");
    }
    //初始化
    this.setNum(num);
  }
})()

Phone.prototype.checkNum = function(num){
  if(/^1[358]\d{9}$/.test(num)){
    return true;
  }else{
    return false;
  }
}

var p1 = new Phone("13312341234");
var p2 = new Phone("15812341234");

p1.call(p2);  //13312341234正在呼叫15812341234

和上面创建的方式大体相似,但这里的构造函数变成了一个内嵌函数,通过外部函数的立即执行被返回,这也就使得外部函数的count能被构造函数访问到,因为外部函数只被加载一次,所以count也只有一个,当创建50个实例的时候,count被赋为50,若继续创建则会报错。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

c++中对类中私有成员中的静态变量初始化

1.static成员的所有者是类本身和对象,但是多有对象拥有一样的静态成员。从而在定义对象时不能通过构造函数对其进行初始化。 2.静态成员不能在类定义里边初始化,只能在class body外初始化。 ...
  • wingWC
  • wingWC
  • 2017年07月23日 11:20
  • 154

c++中可以对类中私有成员中的静态变量初始化吗?

题:我看的书上写的对私有部分的访问可以是公共部分的成员函数,也可以是友员函数,那么可以直接对私有部分的静态成员进行初始化吗? 回答: 1.static成员的所有者是类本身和对象,但是多有对象拥有一...
  • wyt4455
  • wyt4455
  • 2013年03月20日 12:21
  • 688

静态成员、关键字mutable 、公有继承与私有继承、虚函数的基本概念

1、静态成员#include using namespace std; class salary { public: salary(const int b){sal = b;} st...

私有的静态成员变量

一、问题 最近在看>的时候对自己掌握的类的私有的静态成员变量的初始化产生了怀疑,下面就是自己的对与这个知识点的复习与总结 二、探索 1、静态成员变量不能进进行赋值 下面程序会报错 class A { ...

《JavaScript高级程序设计 第三版》学习笔记 (八)块作用域及私有成员

一、模仿块级作用域 1.js不像C和java一样有块级作用域。在C和java中,一对大括号{}决定一个作用域,比如for循环。在js中,变量可以在函数任何一处定义,并且忽略重复定义。变量初始化之前使...

JavaScript中的私有成员

JavaScript 是世界上最被误解的语言。很多人认为它缺乏信息隐藏的特性所以对象不能有私有实例变量和方法。但这是一个误解。JavaScript对象同样可以拥有私有变量。下面就讲解一下...

Private Members In JavaScript(javascript的私有成员)——翻译

翻译大半,发现有人翻译过了,而且翻译地还比较好。但是还是硬着头皮翻下去了,并参考他的做了修改,就作为我翻译e文的第一次吧。 原文:http://javascript.crockford.co...

C#私有成员反射调用类库

  • 2016年04月16日 18:47
  • 20KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript 创建私有成员和静态私有成员
举报原因:
原因补充:

(最多只允许输入30个字)