2016-09-11 81 views
1

不知何故,JS繼承並沒有得到我的頭。我現在嘗試了很多東西,出於某種原因,我無法將方法添加到繼承的對象。Javascript調用函數的繼承

看到我的嘗試,定義B.setC,然後以後不可用。任何提示?

歡呼 湯姆

A = function(value){ 
     this.aValue = value; 
} 


B = function(value){ 
    A.call(this, value); 
    this.bValue=value+value; 
} 

B.prototype = Object.create(A.prototype);//subclass extends superclass 


B.setC = function(value){ 
    this.c = value+value+value; 
    console.log("execution"); 
} 

B.prototype.setD = function(value){ 
    this.D = value+value+value+value; 
    console.log("execution"); 
} 





x = new B("ConstructorParam"); 
x.setC("methodParam");// gives that setC is not a function 
x.setD("methodParam");// works but I added setD to A not B 
+3

這只是一個錯字,你的意思是'B.prototype.setC = ...',但你'B.setC = ...' –

+0

其實這不是一個錯字。我想將setC添加到B而不是A,如果我的理解是正確的,並且我在Chrome中看到了調試,那麼如果我使用B.prototype.setB,則將setB添加到B aka A的原型而不是B。或者我錯過了什麼? – Tom

+0

你的代碼也陷入了[*隱性全局恐怖*](http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html)*(這是我博客上的一篇文章)*:聲明你的變量。 –

回答

3

的混亂似乎來自這個誤會;引用您的評論:

其實這不是一個錯字。我想將setC添加到B而不是A,如果我的理解是正確的,並且我在Chrome中看到了調試,那麼如果我使用B.prototype.setB,則將setB添加到B aka A的原型而不是B。或者我錯過了什麼?

這也是由在問題此評論顯示:

x.setD("methodParam");// works but I added setD to A not B 

B.prototypeAB.prototype是以A.prototype爲原型的對象。您正確地將setD添加到B.prototype;它不以任何方式添加到AA.prototype

如果你想使用setCsetD你表現的方式,你可以把它們無論是在B.prototype(所以他們對B實例訪問)或A.prototype(所以他們訪問對AB實例) 。

如果我們改變B.setC =B.prototype.setC =,使d小寫匹配c,添加一些失蹤var S,以及創建和調用方法時使用較短的值,我們得到這樣的:

var A = function(value){ 
    this.aValue = value; 
}; 

var B = function(value){ 
    A.call(this, value); 
    this.bValue = value + value; 
}; 

B.prototype = Object.create(A.prototype);//subclass extends superclass 

B.setC = function(value){ 
    this.c = value + value + value; 
    console.log("execution"); 
}; 

B.prototype.setD = function(value){ 
    this.d = value + value + value + value; 
    console.log("execution"); 
}; 

var x = new B("b"); 
x.setC("c"); 
x.setD("d"); 

剛過了代碼最後一行,這就是我們在內存(減去了一堆不必要的細節):

 
     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
     |                | 
     \ +−−−−−−−−−−−−−−−+            | 
A−−−−−−−−−>| function |            | 
      +−−−−−−−−−−−−−−−+        +−−−−−−−−−−−−−+ | 
      | prototype  |−−−−−−−−−−−−−−−−−−−−−−−−−−−−>| object | |  
      +−−−−−−−−−−−−−−−+       /+−−−−−−−−−−−−−+ |  
                 | | constructor |−+ 
                 | +−−−−−−−−−−−−−+ 
     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | 
     |           | | 
     \ +−−−−−−−−−−−−−−−+       | | 
B−−−−−−−−−>| function |       | | 
      +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−+ | | 
      | prototype  |−−−>|  object  | | | 
      +−−−−−−−−−−−−−−−+/+−−−−−−−−−−−−−−−−−−+ | | 
           | | constructor  |−+ | 
           | | setC: (function) | | 
           | | setD: (function) | | 
           | | [[Prototype]] |−−−+ 
      +−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−−−+ 
x−−−−−−−−−>| object  | | 
      +−−−−−−−−−−−−−−−+ | 
      | aValue: "a" | | 
      | bValue: "aa" | | 
      | c: "ccc"  | | 
      | d: "dddd"  | | 
      | [[Prototype]] |−−+ 
      +−−−−−−−−−−−−−−−+ 

[[Prototype]]以上就是規範使用的日名e包含對其原型對象的引用的對象的「內部槽」。相比之下,prototype函數的屬性(例如A.prototype)只是函數的一個正常屬性,它指向的對象將使用new作爲其創建的新對象的[[Prototype]],前提是您使用該函數的new


只是爲了完整性,這裏是ES2015 +:

class A { 
    constructor(value) { 
     this.aValue = value; 
    } 
} 

class B extends A { 
    constructor(value) { 
     super(value); 
     this.bValue = value + value; 
    } 

    setC(value) { 
     this.c = value + value + value; 
     console.log("execution"); 
    } 

    setD(value) { 
     this.d = value + value + value + value; 
     console.log("execution"); 
    } 
} 

let x = new B("b"); 
x.setC("c"); 
x.setD("d");