2014-04-13 58 views
1

我正在創建一個相當簡單的Point2D數據結構,我將來可以繼承並說出一個Point3D,而且我已經遵循了所有的指南和類似的問題,但沒有看到幫助解決我的問題。Javascript Prototype:Replacement vs Addition

我定義的Point2D如下:

function Point2D (px, py) 
{ 
    this.x = px; 
    this.y = py; 

    Point2D.prototype = 
    { 
    constructor: Point2D, 

    move:function (mx, my) 
    { 
     this.x = mx; 
     this.y = my; 
    }, 
    translate:function (dx, dy) 
    { 
     this.x += dx; 
     this.y += dy; 
    } 
    }; 
}; 

我實例化對象如下:

var p2d1 = new Point2D(2,3); 

然後我調用的方法之一如下:

p2d1.move(1,2); 

其結果是:

TypeError: Object #<Point2D> has no method 'move' 

我不知道爲什麼我的方法沒有解決。

我已經搞砸了很長一段時間,發現我可以用這種方式聲明Point2D方法,他們會工作。

Point2D.prototype.move = function() {}; 

任何人都可以解釋爲什麼他們替換整個樣機並工作,但添加的功能,以現有的原型確實工作的第一個樣式?

+2

您絕對需要在構造函數外部放置原型分配。 – Bergi

+0

Bergi說什麼,這裏是一個小提琴:http://jsfiddle.net/m7Jqs/ –

+0

達恩 - 它...我設法在我的搜索中錯過了這個問題。 – Austin

回答

2

當您第一次致電new Point()時,Point.prototype仍然是「空」原型。即創建的實例不會繼承任何方法。

您在之後更改(替換)原型該實例已創建。 JavaScript已按值分配,不按引用分配。簡單的例子:

var a = 5; 
var b = {c: a}; 
a = 10; 

b.c仍然是5,因爲分配給a不會改變b.c指。

Point2D.prototype.move = function() {}; 

的作品,因爲你不更換Point2D.prototype,你只是變異現有的對象。

總體而言,分配給*.prototype應該發生構造:

function Point2D (px, py) { 
    this.x = px; 
    this.y = py; 
}; 

Point2D.prototype = { }; 
0

如果你真的想扭轉你的大腦創建Point2D的第二個實例,並觀察它有移動方法可用和工作!

所以這裏是發生了什麼。

define Point2D class 
create instance of Point2D class 
    create initialization object 
    create execution context object per new keyword usage 
    attach prototype to execution context (at this point just Object) 
    run constructor method 
    assign value of x 
    assign value of y 
    assign new prototype value to Point2D class 

你想要做的是將原型設置爲與類定義相同的範圍。

1

我不知道,但定義「類」的聲明中的原型是不尋常的,對我來說,很難確切地定義事情將如何解決。當上工繼承,我傾向於遵循以上這些模式:

function Foo() { 
    this.bar = ... 
} 

Foo.prototype.baz = function() { ... } 

OR

function Foo() { ... } 
function Bar() { ... } 

Foo.prototype = new Bar(); 

OR

Foo.prototype = { 
    blah: ... 
} 

此外,我通常不會手動創建一個 「構造」 特性,因爲這是設置原型的副作用,但我知道一些流行的庫會這樣做。在上面的中間示例中,Foo.prototype.constructor == Bar。