2012-11-13 129 views
4

在我開始嘗試學習backbone.js之前,我一直試圖學習使用JavaScript進行OOP。面向對象的JavaScript編程

我想能夠綁定數據,但我似乎無法使其工作。

我只是做了預算的網站,你可以把一個預算,輸入你已經花了多少錢的簡單protoype,它會告訴你已經走了過來。

function BudgetItem(spent, budget){ 

    this.setSpent = function(spent){ 
     this.spent = spent; 
    } 
    this.setBudget = function(budget){ 
     this.budget = budget; 
    } 
    this.getSpent = function(){ 
     return this.spent; 
    } 
    this.getBudget = function(){ 
     return this.budget; 
    } 

} 

function BudgetType(type){ 
    this.getType = function(){ 
     return type; 
    } 
} 

BudgetType.prototype = new BudgetItem(); 

$(document).ready(function(){ 

    var food = new BudgetType('food'); 

    $('.budget').html(food.getBudget()); 
    $('.editbudget').change(function(){ 
     food.setBudget($('.editbudget').data()) 
    }); 
}) 

這是我迄今的代碼。我不確定我是否做得對。我應該擴大事情嗎?另外,有人可以解釋如何動態數據綁定沒有圖書館?

+2

你並不需要新空房禁地的getter/setter函數,如果你在他們需要額外的功能後,你總是可以在後面加上他們爲的getter/setter屬性,它會工作同樣在公共界面 – Esailija

+0

首先,我建議不要使用jQuery或這樣的圖書館,直到你有一個公司的JS理解。 – SReject

+1

這並不回答你的問題,但如果你想獲得JS,OOP或其他方面的良好處理,你一定要閱讀[Javascript:The Good Parts](http://www.amazon.com/exec/obidos/) ASIN/0596517742/wrrrldwideweb)[Douglas Crockford](http://crockford.com/)。 – prodigitalson

回答

5

首先,我會給你一些理論。 Javascript函數是一個動態對象,就像Object一樣。它具有屬性和方法,更多可以在運行時添加(因此是動態的)。 this關鍵字綁定到新創建的對象,所以,你在做什麼,實際上是創建新的屬性,因爲你第一次傳遞它們的值......這是好的,但對另一位讀者不太清楚。

由用戶創建的每個對象和功能有一個鏈接到一個「隱藏」的原型對象。這是一個匿名(不能通過名稱訪問)的對象,由JavaScript運行時創建,並通過prototype屬性作爲對用戶對象的引用傳遞。 Prototype對象還通過constructor屬性對用戶對象進行引用。綜合起來,現在您可以將函數看作構造函數,以便爲您創建的每個函數創建的類都可以通過函數原型屬性進行訪問。所以,你可以直接添加字段添加到原型對象像這樣:

function BudgetItem(spent) { 
    this.spent = spent 
}   
BudgetItem.prototype.spent = 0; 
BudgetItem.prototype.setSpent = function(spent) { this.spent = spent }; 
BudgetItem.prototype.getSpent = function(){ return this.spent }; 

的另一個問題是傳承與傳遞參數構造函數。同樣,您的版本是有效的,但您在初始化BudgetType時無法傳遞已用和預算值。我會做的是忘記原型,並去:

function BudgetType(type, spent) { 
    var instance = new BudgetItem(spent); 
    instance.type = type; 
    return instance; 
} 

這是接近什麼斯科特Sauyet建議上面,但更強大。現在你可以傳遞兩個參數(和更多)並且有一個更復雜的繼承樹。

最後,你可以做的是通過爲其他自動變量(一個作爲參數傳遞或者在函數內部初始化)提供一個getter來創建私有的(或僞私有的,更精確的)屬性。這是語言的一種特殊功能,它的工作原理是這樣:

function BudgetType(type, spent) { 
    var instance = new BudgetItem(spent); 
    instance.getType = function() { 
     return type; 
    } 
    return instance; 
} 

現在,您可以訪問由obj.getType(構造函數中傳遞的「類型」),但不能覆蓋的初始值。即使您定義了obj.type ='New Value',getType()也會返回傳遞的初始參數,因爲它引用了另一個上下文,該對象是在對象初始化時創建的,並且由於關閉而從未釋放。

希望幫助...

+0

完美!謝謝 – allouis

1

,如果你希望對象引用同一個成員的所有實例/值可以使用閉包:如果你想建立從其他對象的對象

// create a constrctor for you object wrapped in a closure 
myCon = (function() { 

    // define shared members up here 
    var mySharedObj = new function() { 
     this.member = "a"; 
    }(); 

    // return the actual constructor 
    return function() { 
     this.mySharedObj = mySharedObj; 
    } 
}()); 

// create two instances of the object 
var a = new myCon(); 
var b = new myCon(); 


// Altering the shared object from one 
a.mySharedObj.member = "b"; 

// Alters it for all 
console.log(b.mySharedObj.member); 





(排序像其他語言'class whatever extends baseClass),但不希望它們通過引用(而不是數值的克隆)共享值,則可以使用類似以下內容的東西:

Object.prototype.extendsUpon = (function (_prop, _args) { 
    return function (base) { 
     for (var key in base) { 
      if (_prop.call(base, key)) { 
       this[key] = base[key]; 
      } 
     } 

     function con(child){ 
      this.constructor = child; 
     } 
     con.prototype = base.prototype; 

     this.prototype = new con(this); 
     this.__base__ = base.prototype; 

     var args = _args.call(arguments); 
     args.shift(); 
     base.constructor.apply(this, args); 
    } 
}(Object.prototype.hasOwnProperty, Array.prototype.slice)); 


然後建立對象ontop的對象:

// Base Object Constructor 
function Fruit(name) { 
    this.fruitname = name; 
} 
Fruit.prototype.yum = function() { 
    return "I had an " + this.fruitname; 
} 

// Object constructor that derives from the Base Object 
function Favorite() { 

    // Derive this object from a specified base object: 
    //  @arg0 -> Object Constructor to use as base 
    //  @arg1+ -> arguments passed to the BaseObject's constructor 
    this.extendsUpon(Fruit, "apple"); 

    // From here proceed as usual 

    // To access members from the base object that have been over-written, 
    // use "this.__base__.MEMBER.apply(this, arguments)" 
} 
Favorite.prototype.yum = function() { 
    return this.__base__.yum.apply(this) + " and it was my favorite"; 
} 
var mmm = new Favorite(); 

// Outputs: "I had an apple and it was my favorite" 
mmm.yum(); 
+0

這對我來說有點令人困惑,但我會努力工作,但是它非常豐富,我非常感謝你的時間,謝謝! – allouis