js中方法类的拟静态属性、公有属性、私有属性

今天斗完地主,发现芋头童鞋在群里面提了一个很有趣的一个问题:

下列代码使Test方法类具有一个静态属性arr(数组)

var Test=function(){
}
Test.prototype={
    arr:[]
}
var test1=new Test();
test1.arr.push('ddd')
var test2=new Test();
alert(test2.arr.length) //1

他问为什么两个实例(test1和test2)会共用一个arr数组。他要的是独立实例具有独立的那个arr(数组)属性,我刚开始还以为他问怎样可以共用一个数组。

后来给他提了一个解决方法:

下列代码使隶属于Test方法类的两个实例test1和test2具有各自的arr(数组)属性

var Test=function(){
    this.arr=[];//原理很简单,初始化的时候使当前实例(this)的arr(数组)属性(来源于对象原型:Test)从新指向空数组
}
Test.prototype={
    arr:[]//使分别两次实例化的时候具有两个arr(数组),但是注意是指向同一个内存位置
}
var test1=new Test();
test1.arr.push('ddd')
var test2=new Test();
alert(test2.arr.length) //0

好,可以总结的有以下知识:

先看一下我整理过的例子

/***********带静态属性和方法的原型方法类的定义****************/
var Test=function(string){
    var privateArg='abc';//函数的私有变量,私有属性定义
    this.publicString=string;//为之后的实例初始化一个公有的字符串
    this.publicArr=[];//为之后的实例初始化一个公有的数组
    this.publicFunction=function(){//为之后的实例初始化一个公有的方法
	alert('I m the public function.'+'my string is "'+this.publicString+'"');
    }
}
//追加静态属性和方法
Test.prototype={
    staticString:'static',
    staticArr:[],
    staticFunction:function(){Test.prototype.staticString='alreadySetByFunc';}
};
 
/*************对静态属性和方法的研究******************/
var test1=new Test('p1');//实例化得到test1新实例
//我要修改静态的字符串,方法1:直接用原型类赋值
Test.prototype.staticString='s1';//通过原型类更改静态属性staticString
alert(test1.staticString);
var test2=new Test('p2');
//我要修改静态的字符串,方法2:实例通过静态方法赋值
test2.staticFunction(); //通过类的实例调用原型类的静态方法改变静态属性
alert(test2.staticString);
//通过赋值实例的静态属性(实际上就是来源于原型类的静态属性[一个复制])不能更改原型类的静态属性
test2.staticString='s2';
alert(test1.staticString);//静态属性没有被修改
alert(Test.prototype.staticString);
//以下有个问题你可能觉得奇怪,为什么
test1.staticArr.push('newArg');//修改数组
alert(test2.staticArr);//为什么原型类的静态数组属性也发生改变了!?原因很简单:实际上实例化的时候新的实例实际上复制了原型类的静态属性和方法,而数组的复制,大家知道,实际上只是指向的复制,所以当任意一方对数据修改,其他引用到该数组的地方都会发生改变。
 
/***************对公有属性和方法的研究******************/
//Test.publicFunction(); //该句代码会出错,原因在于:对于Test方法类并没有公有的publicFunction方法,重点在理解this,在没有被实例化的时候this指的是window
test1.publicFunction();//在实例化的时候新的实例被初始化一个publicFunction方法
test2.publicFunction();//同上
test1.publicArr.push('newArg');//修改实例test1的公有数组
alert(test2.publicArr);//发现输出为空,表明实例test2的公有数组没有发生变化
 
/***************对私有属性和方法的研究******************/
alert(test2.privateArg);//为undefine,原因在于私有属性不能被实例引用

知识点:

  • 定义方法类的拟静态属性或者拟静态方法只要在对象原型的prototype属性内定义即可。
  • 修改静态属性有两种方法,第一种:直接原型类更改静态属性进行赋值;第二种:通过实例调用静态方法赋值;不能通过修改实例直接修改
  • 实例化的时候实际上:新的实例从新获得静态属性和方法,而这些静态属性是原型类静态属性和方法的一个拷贝(因此要注意引用值类型数据属性(如数组)的复制)
  • 原型类的定义中this并不是指原型类本身,而是指window,到实例化的时候this指的是实例本身,所以直接用原型类调用公有属性出错。
  • 不同实例的公有属性和方法独立不相互影响,原因在于它们不是对原型类公有方法和属性的复制,因此不存在引用值类型数据的同步更改问题
  • 方法内部定义的变量可以看做为方法类的私有变量,实例无法引用

这样总结一下,获益良多,以上为本人个人总结,如有错误无限欢迎指出,我会及时勘误。

最后原创文章,转载请注明出处:http://xiebiji.com/2010/01/static_js/

1 Response to js中方法类的拟静态属性、公有属性... »

  1. 豪情 评论 2011-06-05 10:10

    注释的字体太难阅读了,何必呢?

    回复

Leave a Reply

Email address is not published

You should say a Chinese word to pass spam check. If you can not input Chinese, just copy 你好 and paste them into comment text box.