2014-01-26 131 views
3

作爲開發人員使用OOP背景(c#,Java)OOP JavaScript對我來說是野馬。我正在學習語言的堅果和螺栓,然後跳上圖書館(我錯了嗎?);所以,我查了幾十本關於對象,函數等的書籍/教程。學習了幾種創建對象的方法,但幾乎每個JS庫中使用的語法讓我感到困惑。即JavaScript語法:什麼是({})它是一個函數還是對象?

var Person = Backbone.extend.Model({ 
//pretty complex staff 
}) 

什麼是模型幕後?目的?功能?

+0

不應該是'Backbone.Model.extend'嗎? –

回答

13

這不是正確的主幹語法。實際上應該是:

Backbone.Model.extend({ 

}); 

在這種情況下,extend是一個函數。請注意,您使用()來調用它。然而,JavaScript中的函數也是對象(稍後更多)。您可能會對其內部的{}感到困惑。這是因爲您將該對象作爲參數傳遞給該函數。

如果extend是一個函數,期望一個字符串作爲參數/參數,它看起來像這樣:extend('some string')。在這種情況下,它正在採取一個對象。例如:

var someObject = { 
    someProperty: 'someValue' 
} 
var Person = Backbone.Model.extend(someObject); 

是一樣的:

var Person = Backbone.Model.extend({ 
    someProperty: 'someValue' 
}); 

這裏只是一個怎麼可能看在功能樣本:

Backbone.Model.extend = function(obj) { 
    console.log(obj.someProperty); //logs "someValue" 
} 

正如我所說的,在JavaScript中,函數也是對象。其實,大部分東西都是物體。我建議你對此進行更多的研究。因爲它不是你的問題的重點,我只是簡單地表明:

var someObj = { 
    someProperty: '123' 
}; 
console.log(someObj.someProperty); //logs "123" 

var someFunction = function() { 

}; 
someFunction.someProperty = '123'; 
console.log(someFunction.someProperty); //logs "123" 

雖然,這將是更好地加入到原型,以便繼承會像這樣:

someFunction.prototype.someProperty = '123'; 
var foo = new someFunction(); 
console.log(foo.someProperty); //logs "123" 

Here's a little demo you can mess with (click).

所以..總之,JavaScript是雙贏的。

+1

要添加可能會澄清事物的內容,在調用函數之前,將評估作爲extend()參數的對象{}。所以你基本上將一組鍵/值作爲參數傳遞給擴展函數。 – GameAlchemist

2

您確定您輸入的內容正確嗎?我想你扭轉了Modelextend的順序。我正在查看文檔,並且我看到:

模型是任何JavaScript應用程序的核心,包含交互式數據以及圍繞它的大部分邏輯:轉換,驗證,計算的屬性和訪問控制。您可以使用特定於域的方法來擴展Backbone.Model,並且Model提供了一組用於管理更改的基本功能。

extend函數在許多Javascript庫中實現:Backbone,Underscore和jQuery。它所做的是獲取一個對象並向其添加方法和實例變量。畢竟在Javascript中,對象只是散列。這創建了一個有幾個方法和數據的對象。

var counter = {}; 
counter.count = 0; 
counter.increment = function() { 
    this.count++; 
} 
counter.decrement = function() { 
    this.count--; 
} 

如果你想繼承,您使用對象或它的構造函數的prototype財產。 extend方法是一種模擬這種方法。下面是更多的骨幹文檔:

extendBackbone.Model.extend(屬性,[classProperties])

創建模型類你自己的,你擴展Backbone.Model並提供實例屬性,以及作爲可選的classProperties直接附加到構造函數。

擴展正確設置原型鏈,因此使用擴展創建的子類可以進一步擴展和子類化,只要你喜歡。

var Note = Backbone.Model.extend({ 

    initialize: function() { ... }, 

    author: function() { ... }, 

    coordinates: function() { ... }, 

    allowedToEdit: function(account) { 
     return true; 
    } 

}); 

在傳統的JavaScript中,你會寫:在JavaScript

function Note() { 
    this.initialize = function() {...}; 
    this.author  = function() {...}; 
    this.coordinates = function() {...}; 
    this.allowedToEdit = function(account) { 
     return true; 
    }; 
} 

Note.prototype = new Model(); // Inheritance. 

傳承讓我想起了Perl的格言:有做到這一點的方法不止一種。

+0

是的,我錯位擴展:) – brocode

1

歡迎計算器,

我強烈建議你看看Douglas Crockford's Website,也有insightfull videos in YUI Theater - 道格拉斯的那些啓動。他是發現JavaScript has good parts的人。我還發現John Resig's Secrets of the JavaScript Ninja非常有益於克服語言(約翰是無所不在的jQuery Library的創造者)。我會進一步建議你看看一些庫(和他們的代碼 - 我就是這麼學的 - 從jQuery開始)。有a ton of other libraries在那裏,但一次一步:-)。

現在你的問題: Backbone.Model是一個構造函數,通常你會像Java中使用它new Backbone.Model({ configOption: true, ... })。但像JavaScript一樣多汁,它可以讓你在引擎蓋下做些瘋狂的事情。例如,您可以實現自己的OOP類實現,或者您可以像在Scheme或Lisp中那樣以功能樣式進行編程。你在這裏看到的是Backbone自己的子類型包裝器(實際上任何體面的JS庫都提供了一些方法來實現這一點)。 的代碼實際上是做一些沿此線:

// Creating a sub type of the Backbone.Model *class* - it's not really 
// a class like in Java or C# but rather a (constructor) function. 
var Person = Backbone.Model.extend({ 
    defaults: { 
     hasTheOneRing: true 
    }, 
    initialize: function (hasTheOneRing) { 
     // Note that Backbone is implementing getters/setters 
     // under the hood so you can listen for change events later 
     this.set('hasTheOneRing', hasTheOneRing); 
    } 
    // More configuration ... 
}); 

// Person now is a constructor function that creates instances 
// of it's *class* when you create an object with it 
var frodo = new Person(true), 
    sam = new Person(); // Note that you can supply as many arguments as you wish 

// Frodo has the ring 
console.log(frodo.get('hasTheOneRing')); 

// Sam doesn't have the ring (well not all the time) 
console.log(sam.get('hasTheOneRing')); 

// In plain old JavaScript the sub typing mechanism works a little bit like this: 

// A constructor function is just a function 
function Person() { 
    // JS doesn't have the notion of *super* or *base* but you 
    // can emulate the behavior as many libraries do in the wild 
    Backbone.Model.call(this); 
} 

// The prototype of a person is based on that of a Backbone.Model 
Person.prototype = Object.create(Backbone.Model.prototype); 

// Object.create has not been there since the beginning. After 
// Douglas Crockford discovered the good parts this function 
// has been adapted into the standard portfolio of every modern browser 
// what it does is essentially just: 
function create(object) { 
    // There's actually more going on in here but you get the idea 
    function F() {} 
    F.prototype = object; 
    return new F(); 
} 

// So this means almost the same 
Person.prototype = new Backbone.Model(); 

我越來越愛JS的方式就是閱讀庫代碼 - 和Backbone is open source等有讀取和迷死感到驚訝。我認爲JS只是純文本傳送的事實對於在生態系統中強大的語言產生了巨大的影響,甚至微軟也無法阻止它。

給語言一個嘗試,當它點擊時你很可能會開始喜歡它:-)。

快樂編碼!

+0

是的,我真的進入它。這是不同的,同時可愛 – brocode

相關問題