2013-12-17 100 views
1

我知道C#的一點點,現在我已經開始使用JavaScript,並且在理解基礎知識時遇到了一些問題。需要Javascript基本說明

這裏是我的代碼示例:

function BaseFunc(x, y) { 
    this.X = x; 
    this.Y = y; 
} 

function DerivedFunc(x, y, z) { 
    this.Z = z; 
    BaseFunc.call(this, x, y); 
} 

DerivedFunc.prototype = new BaseFunc; 


function Test() { 
    var d = DerivedFunc(1, 2, 3); 
    var b = new BaseFunc(4, 5); 
    d.sayHello(); 
    b.sayHello(); 
} 

DerivedFunc.prototype.sayHello = function() { 
    alert("Result is: " + (this.X + this.Y + this.Z)); 
} 

在上面的代碼中,我試圖讓一個繼承。

一切看起來不錯,直到我到達線BaseFunc.call(this, x, y);這條線應該調用基本功能,但在這種情況下this的用途是什麼。 只是爲了滿足方法call的簽名,它是如何工作的?

第二個問題是,在JavaScript中,我們可以動態添加任何東西, 在我的情況下,我添加sayHello()屬性併爲其分配一個匿名函數。 像DerivedFunc.prototype.sayHello,我添加屬性/方法BaseFuncDerivedFunc,因爲它被添加到原型,它應該被添加到BaseFunc據我瞭解。但是當我執行上面的代碼時,我得到的錯誤是sayHello未定義。

有人可以澄清我什麼是錯的,謝謝?

+0

'變種d一些想法= DerivedFunc(1,2,3);'這是原因之一[道格拉斯克羅克福德(HTTP://的javascript .crockford.com /)在他的[書籍](http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb)中反對使用JavaScript中的「class」:它的語法正確,沒有錯誤發生,但是你可能沒有得到你想要的。你實際上可能意指'var d = new DerivedFunc(1,2,3)'。 – Passerby

+0

@Passerby:有一百萬個編程錯誤在語法上是正確的,不會引發錯誤,但不會執行程序員的目標。我不知道爲什麼人們對這個特別的人非常着迷,它並不比其他人差。 –

+0

閱讀[MDN關於面向對象的JavaScript文章](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript),您可能會從中受益。 –

回答

1

一切看起來不錯,直到我到達線BaseFunc.call(this,x,y);這一行應該調用基本函數,但是在這種情況下,這有什麼用處。

它的存在,使調用BaseFunc內,this有它在調用DerivedFunc相同的值,從而使線this.X = x;和這樣的BaseFunc被分配到正確的實例。 (調用函數設置this特定的值是什麼功能的.call.apply方法做。)

但是,當我執行上面的代碼,我得到錯誤的sayHello沒有定義。

如果,你遇到的麻煩是d.sayHello,那是因爲你已經錯過了new操作就行了d = DerivedFunc(1, 2, 3);。由於DerivedFunc只是作爲函數調用而不是通過new,沒有任何返回值,因此d將爲undefined


請注意,繼承方式雖然很普遍,但存在問題。主要的問題是在這裏:

DerivedFunc.prototype = new BaseFunc; 

您正在嘗試使用旨在創建實例的函數,它接受的參數,以創建原型實例DerivedFunc將分配到的東西。那麼BaseFunc應該如何處理缺失的參數呢?然後,再次調用(從DerivedFunc)初始化實例。 BaseFunc正在做雙重任務。

這裏是你如何改正,首先囉嗦版:

function x() { } 
x.prototype = BaseFunc.prototype; 
DerivedFunc.prototype = new x; 
DerivedFunc.prototype.constructor = DerivedFunc; 

或者,如果你可以依靠ES5的Object.create

DerivedFunc.prototype = Object.create(BaseFunc.prototype); 
DerivedFunc.prototype.constructor = DerivedFunc; 

現在我們不是要求BaseFunc創建原型,但我們仍然將其作爲DerivedFuncprototype對象的基礎原型。我們不再存在如何處理BaseFunc的參數的問題,並且BaseFunc僅以其設計被調用的方式調用:初始化單個實例,而不是初始化原型。

當然,不是每次我們想要派生構造函數時都要編寫它,你需要一個幫助腳本。

如果您對JavaScript繼承層次結構感興趣,您可能想看看我的短Lineage腳本  —不一定要使用,但瞭解這些工作是如何工作的。 page showing how to do things without the script和比較用腳本做它們可能特別有用。

+0

Crowder:感謝Sir for your answer我把新的和它適用於派生但爲什麼我不能因爲我通過說Derived.prototype.sayHello來添加它,所以請在BaseFunc上說你好! – ShrShr

+0

@ShrShr:因爲您沒有將它添加到'BaseFunc.prototype'中,該對象被指定爲通過'new BaseFunc'創建的實例的原型。相反,您將其分配給了「DerivedFunc.prototype」,因此它僅適用於使用* that *作爲其原型創建的實例(在此情況下通過「新DerivedFunc」創建的實例)。雖然'DerivedFunc.prototype'使用'BaseFunc.prototype'作爲它的原型,它們是單獨的對象,向'DerivedFunc.prototype'添加屬性對'BaseFunc.prototype'沒有影響。 –

0

嗨,請通過以下。我希望它會給你傳承與()調用

<script type="text/javascript"> 

    //inheritence 
    function parent() { 
     this.add = function (a, b) { 
      return a + b; 
     } 
     this.subtract = function (a, b) { 
      return a - b; 
     } 
    } 

    function child() { 
     this.display = function() { 
      alert(this.add(11, 23)); 
     } 
    } 

    child.prototype = new parent();   //child extends parent.... inheritence 
    child.prototype.constructor = child; //resetting constructor property 

    var obj = new child(); 
    obj.display(); 

    /* 
    .call() and .apply() 
    They allow our objects to borrow methods from other objects and invoke them as their own 
    */ 
    var person = { 
     name: 'Kundan', 
     display: function(name) { 
      alert(this.name + ' welcomes ' + name); 
     } 
    }; 

    person.display('Dipa'); //Kundan welcomes Dipa 

    var person1 = { name: 'Java Master' }; 
    person.display.call(person1, 'Sachin'); //Java Master welcomes Sachin 
    //here person1 object is passed in the call function 
    //if we are using call inside a function and want to pass the same function object then this is passed in call function 
    /* 
    We can pass more parameters as follows 

    person.display.call(person1, 'a', 'b', 'c'); 

    The method apply() works the same way as call() but with the difference that all parameters you want to pass to the method of the other object are passed as an array. 
    */ 
     person.display.apply(person1, ['a', 'b', 'c']); 



</script>