Stay Hungry,Stay Foolish!

继承Prototype实现语句不能写在动态原型法中的理解

  阅读javascript高级编程中, 对动态原型法中写Prototype继承父类对象的不可行的现象,不甚理解。

书上说是技术原因,如下有问题代码:

 

但是把protype语句移到构造函数后面,就OK,如下图:

 

  找到代码 https://raw.githubusercontent.com/nzakas/professional-javascript/master/edition1/ch04/DynamicPrototypePolygonExample.htm

 

通过实验确定有如下解释:

1、 Prototype就是一个对象,对象中的所有的属性和方法, 都是实例化的内容。

2、 构造函数在被new生成的时候,此实例的Prototype对应,new之前此类的Prototype。

3、 构造函数中,修改Prototype,不影响即将诞生的实例的Prototype按照之前的内容生成。

 

如果将Triangle Prototype赋值,放在构造函数中, 则第一次new动作的时候, 此类的Prototype对象是空对象 {},

没有任何属性和方法,则第一次new出的实例的Prototype为 {}, 没有 getArea 函数;

但是第一次执行之后, Prototype 切换为 new Polygon 对象, 且不再改变, getArea 函数也被重载, 在第二次及之后的new Triangle都是有 getArea 方法的。

 

测试代码:

<html>
<head>
<title>Example</title>
</head>
<body>
<script type="text/javascript">

function Polygon(iSides) {
    this.sides  = iSides;
    console.log("con poly")
    if (typeof Polygon._initialized == "undefined") {

        Polygon.prototype.getArea = function () {
            return 0;
        };    
        
        Polygon._initialized = true;
    }
}



function Triangle(iBase, iHeight) {
    Polygon.call(this, 3);
    this.base = iBase;
    this.height = iHeight;
    
    if (typeof Triangle._initialized == "undefined") {
        /* 只要有对 Prototype 指向对象的修改, 
            则继承和覆盖都不生效  */
        //Triangle.prototype = new Polygon();
        
        /* 如果仅仅是从Polygon实例中获取方法,
            并赋值给Prototype,则是OK的  */
        var pobj = new Polygon();
        Triangle.prototype.getArea = pobj.getArea;
        
        Triangle.prototype.getArea = function () {
            return 0.5 * this.base * this.height;
        };    
        
        Triangle._initialized = true;
    }
}


function Rectangle(iLength, iWidth) {
    Polygon.call(this, 4);
    this.length = iLength;
    this.width = iWidth;
    
    if (typeof Rectangle._initialized == "undefined") {
        Rectangle.prototype.getArea = function () {
            return this.length * this.width;
        };    
        
        Rectangle._initialized = true;
    }
}
/* retangle 非动态原型中实现继承 OK */
Rectangle.prototype = new Polygon();

/* 构造函数中Prototype对象没有改变, 
在构造函数中有对getArea修改, 不影响实例化的对象有getArea */
var Polygon = new Polygon(12);
alert("Polygon.sides="+Polygon.sides)
alert("Polygon.getArea="+Polygon.getArea())

var triangle = new Triangle(12, 4);
/* 动态原型法中,只要有对 Prototype 指向对象的修改, 
    则继承和覆盖都不生效,对于第一次new不生效, 对于第二次生效  */
//var triangle1 = new Triangle(12, 4);
var rectangle = new Rectangle(22, 10);

alert(triangle.sides);
alert(triangle.getArea());
//alert(triangle1.getArea());

alert(rectangle.sides);
alert(rectangle.getArea());

</script>
 
</body>
</html>

 

 

 

 

 

posted @ 2014-05-14 00:32  lightsong  阅读(288)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel