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

私有方法和属性

在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,若继续创建则会报错。

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

时间: 2024-10-17 13:18:16

javascript 创建私有成员和静态私有成员的相关文章

Cocos2d-x 3.1.1 学习日志3--C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员

有关const成员.static成员.const static成员的初始化: 1.const成员:只能在构造函数后的初始化列表中初始化 2.static成员:初始化在类外,且不加static修饰 3.const static成员:类只有唯一一份拷贝,且数值不能改变.因此,可以在类中声明处初始化,也可以像static在类外初始化 #include <iostream> using std::cout; using std::endl; class base { public: base(int

C++类中常量数据成员和静态数据成员初始化

常量数据成员初始化原则: 在每一个构造函数的初始化列表中初始化 静态数据成员初始化原则: 类内声明,类外初始化(因为它是属于类的,不能每构造一个对象就初始化一次) // test_max.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include <iostream> #include <vector> using namespace std; class A { public: A(int i):a(0) {} A():

c++初始化常量数据成员、静态数据成员。常量静态数据成员

有关const成员.static成员.const static成员的初始化: 1.const成员:只能在构造函数后的初始化列表中初始化 2.static成员:初始化在类外,且不加static修饰 3.const static成员:类只有唯一一份拷贝,且数值不能改变.因此,可以在类中声明处初始化,也可以像static在类外初始化 示例:   #include <iostream> using std::cout; using std::endl; class base { public: bas

关于私有变量,静态私有变量

有权访问私有变量和私有函数的公有方法称之为特权方法,对象上创建特权方法的方式有两种. 第一种:直接在构造函数中定义特权方法,基本模式如下 function MyObject(){ var privateVariable = 10; function privateFunction(){ alert(1); } this.publicMethod = function(){ privateVariable++; return privateFunction(); }//特权方法 } var aa

js:私有变量和静态私有变量 | 访问私有属性

C++静态成员函数和静态数据成员

当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享.各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关.静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关. 静态数据成员的用途之一是统计有多少个对象实际存在. 静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的.也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一

C++ 静态数据成员和静态成员函数

一 静态数据成员: 1.静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中,因为这样做会引起重复定义这样的错误.即使加上#ifndef #define #endif或者#pragma once也不行. 其定义方式与全局变量相同.举例如下: xxx.h文件 class base{ private: static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持. }; xxx.cpp文件 con

在c++中,静态数据成员可以被非静态成员函数调用吗?如果可以调用的话那为什么还要定义静态成员函数呢

静态数据成员可以被非静态成员函数访问.但静态成员函数只能访问静态数据成员.静态数据成员从属于某一个类,而不是某一个类的 对象.同理,静态成员函数也是一样. 追问 定义静态成员函数的作用有何在呢 回答 静态成员函数隶属于类,不用实例化对象,就可以直接调用静态成员函数来操作静态数据成员 提问者评价 太给力了,你的回答完美解决了我的问题!

C++静态数据成员与静态成员函数

一般情况下,如果有n个同类的对象,那么每一个对象都分别有自己的数据成员,不同对象的数据成员各自有值,互不相干.但是有时人们希望有某一个或几个数据成员为所有对象所共有,这样可以实现数据共享. 可以使用全局变量来达到共享数据的目的.例如在一个程序文件中有多个函数,每一个函数都可以改变全局变量的值,全局变量的值为各函数共享.但是用全局变量的安全性得不到保证,由于在各处都可以自由地修改全局变量的值,很有可能偶然失误,全局变量的值就被修改,导致程序的失败.因此在实际工作中很少使用全局变量. 如果想在同类的