最近在学习javascript中的prototype,对其也有了一定的理解。参阅Javascript王者归来

首先一个简单的例子:


function dwn(s)
{
    document.write(s + "<br/>");
}
function ClassA(x, y)
{
    
if(x) this.x = x;
    
if(y) this.y = y;
}
ClassA.prototype.x 
= 0;
ClassA.prototype.y 
= 0;
var a 
= new ClassA(34);
dwn(a.x);
var b 
= new ClassA;
dwn(b.y);
</script>

 

prototype作用一:

 

这里ClassA的原型有x,y且都为0;

var a = new ClassA(3, 4);
dwn(a.x); //由上面的if(x) this.x = x可知对象a已经有它的属性x;
var b = new ClassA;
dwn(b.y); //这里创建对象的方法为new ClassA,b本身并没有y这个属性,这个时候它在它的prototype中找这个属性,之后就得到b.y为0;

补充:如果上一行的b.prototype也没有y这个属性,那么它会继续住上找,即从b.prototype中的prototype去找这个y属性,一直找下去。

当然也可以删除某对象的属性,而直接返回prototype中的属性,代码如下:


function dwn(s)
{
    document.write(s + "<br/>");
}
function ClassA(x, y)
{
    
if(x) this.x = x;
    
if(y) this.y = y;
}
ClassA.prototype.x 
= 0;
ClassA.prototype.y 
= 0;
var a 
= new ClassA(34);
delete a.x; 
// 与上段代码相比,仅此不同
dwn(a.x);  // 这时去找原型中的属性x
var b = new ClassA;
dwn(b.y);
</script>

 

请看以下的代码:


function Point(x, y)
{
    this.x = x;
    
this.y = y;
}
Point.prototype.x 
= 0;
Point.prototype.y 
= 0;
function LineSegment(p1, p2)
{
    var m_FristPoint 
= p1;
    var m_SecondPoint 
= p2;

    var m_width 
= {
        valueOf : function(){
return Math.abs(p1.x - p2.x)},
        toString : function(){
return Math.abs(p1.x - p2.x)}
    }
    var m_height 
= {
        valueOf : function(){
return Math.abs(p1.y - p2.y)},
        toString : function(){
return Math.abs(p1.y - p2.y)}
    }
    
this.getFirstPoint = function()
    {
        
return m_FristPoint;
    }
    
this.getSecondPoint = function()
    {
        
return m_SecondPoint;
    }
    
    
this.length = {
        valueOf : function(){
return Math.sqrt(m_width * m_width + m_height * m_height)},
        toString : function(){
return Math.sqrt(m_width * m_width + m_height * m_height)}
    }
}
var p1 
= new Point(22);
var p2 
= new  Point(55);
var line 
= new LineSegment(p1, p2);
var lp 
= line.getFirstPoint();
lp.x 
= 100;
alert(line.getFirstPoint().x);
alert(line.length);
</script>

如上所示:lp改变了,两点之间的长度也改变了。原因就是不小心改变了lp的值。

prototype作用一:返回一个临时的类型,就不怕原数据给修改了。

改写getFirstPoint()中的代码

this.getFirstPoint = function()
 {
  function GETTER(){};
  GETTER.prototype = m_FristPoint;
  return new GETTER(); // 改变这个对m_FristPoint没有影响,从未修改m_FristPoint。
 }

就这样就保证了m_FristPoint的只读性。

prototype作用二:创建大量副本

var p1 = new Point(1, 2);
var points = [];
var PointPrototype = function(){};
PointProtoype.prototype = p1;
for(var i = 0; i < 10000; i++)
{
 points[i] = new PointPrototype();
}

这样创建对象很快,因为PointPrototype 只是空函数。但是PointPrototype的却拥有p1的特性。

prototype作用三:定义静态方法

function Point(x, y)
{
 this.x = x;
 this.y = y;
}
Point.prototype.distance = function()
{
 return Math.sqrt(this.x * this.x + this.y * this.y);
}

在这个例子中,用this.distance = function(){}也可以定义Point对象的distance()方法。即:

function Point(x, y)
{
 this.x = x;
 this.y = y;
 this.distance = function()
 {
  return Math.sqrt(this.x * this.x + this.y * this.y);
 }
}

但是当调用构造函数时对this.distance的赋值操作和函数构造,如果程序里构造对象的次数很多的话,时间空间的节省是非常明显的。

用了prototype定义静态方法,所有实例共享唯一的副本,这与this.distance很大不同。

相关文章:

  • 2021-12-22
  • 2021-05-16
猜你喜欢
  • 2022-12-23
  • 2021-11-11
  • 2021-08-15
  • 2021-09-13
  • 2021-10-13
  • 2021-07-10
相关资源
相似解决方案