萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> Backbone.js的一些使用技巧

Backbone.js的一些使用技巧

   這篇文章主要介紹了Backbone.js的一些使用技巧,Backbone.js是一款人氣JavaScript庫,需要的朋友可以參考下

  自從3年前Backbone.js發布第一版以來,Backbone.js就成為一個流行的開源JavaScript “MV*”框架,並獲得人們的青睐。盡管Backbone.js給JavaScript應用提供了框架,但是它仍然給開發者留有很多設計模式供選擇,不管怎樣,當開發者第一次使用Backbone.js時還會產生很多普遍的問題的。

  因此,在這篇文章中,我們將介紹很多不同的設計模式供你在Backbone.js應用中使用,而且我們也會一同來看看對於開發者來說會產生很多普遍的有關性能伸縮的問題。

  對象深度拷貝

  JavaScript對待所有原生類型變量是傳值。所以,當變量被引用時就傳遞了變量的值。

  ?

1 2 var helloWorld = “Hello World”; var helloWorldCopy = helloWorld;

  舉個例子,上面的代碼將變量helloWorldCopy的值設置為變量helloWorld的值。這樣, 自從它的值被復制之後,所有修改helloWorldCopy的值不會修改helloWorld的值。JavaScript對待所有非原始類型的變量時傳引用,這就意味著當變量傳遞的時候將會傳遞內存地址引用。

  ?

1 2 3 4 var helloWorld = { ‘hello': ‘world' } var helloWorldCopy = helloWorld;

  舉個例子,上面的代碼將設置helloWorldCopy為helloWorld的引用,而且,也許你會猜到任何修改helooWorldCopy的值都會直接導致helloWorld值的變化。如果你想要helloWorld的拷貝,你可以創建一個拷貝對象即可。

  也許你會想到“為什麼Backbone.js可以解釋為所有的工作都是通過傳遞引用?”事實上,Backbone.js不會拷貝對象,這將意味著如果你從模型裡調用.get()方法獲得一個對象,任何給這個對象的修改都會直接修改原來的對象。讓我們一起來看一個例子來闡明哪裡會發生這樣的情況。如果你有個如下的Person模型:

  ?

1 2 3 4 5 6 7 8 9 10 11 var Person = Backbone.Model.extend({ defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 78701 } } });

  這樣你就創建了一個新的person對象:

  ?

1 2 3 var person = new Person({ 'name': 'Phillip W' });

  現在我們來對新對象的一些屬性進行操作操作:

  person.set('name', 'Phillip W.', { validate: true });

  上面的代碼成功的給person對象的name屬性賦了值。現在我們在來操作person對象的地址屬性。當然,在我們這樣做之前先驗證一下地址屬性。

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var Person = Backbone.Model.extend({ validate: function(attributes) {   if(isNaN(attributes.address.zipCode)) return "Address ZIP code must be a number!"; },   defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 78701 } } });

  現在,讓我們試圖給地址屬性設置一個不正確的ZIP代碼。

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 var address = person.get('address'); address.zipCode = 'Hello World'; // Raises an error since the ZIP code is invalid person.set('address', address, { validate: true }); console.log(person.get('address')); /* Prints an object with these properties. { 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 'Hello World' } */

  這將會怎樣呢?我們的驗證出現了錯誤!為什麼屬性依舊被改變了?前邊我們說過,Backbone.js不會拷貝模型屬性;它會返回你所請求的一切。這樣,你也許會猜到,如果你需要一個對象,你將得到這個對象的引用,對這個對象的任何操作都會直接改變模型裡的對象。如果你要debug,這可能將把你帶入到無底的兔子黑洞。

  這個問題對於新的Backbone.js使用要引起注意,甚至對於老練的JavaScript程序員有時也會沒有提防。這個問題在GitHub的Backbone.js討論組中有很激烈的討論。正如Jeremy Ashkenas指出,執行一個深的對象引用是個很難解決的難題,一個很深的對象引用是要花費很大代價的。

  幸運的,jQuery 提供了一個深度拷貝功能來實現,$.extend. 如同, Underscore.js ,一個Backbone.js的依靠,提供_.extend 方法,但是我必須避免使用它,因為它沒有執行一份是個深度的復制,Lo-Dash, Underscore.js的一個分叉版本,提供了對象一個深度克隆的_.clone 方法的選項。然而,我使用 $.extend 方法的模型使用的語法規則去執行一個任意對象的深度克隆。記得通過後,結果它執行的是一個深度的克隆方法

  ?

1 var address = $.extend(true, {}, person.address);

  我們現在快速准確的復制一個theaddressobject?,並且我們能夠更改它對於我們要點沒有包括在內的我們不用擔心會更改它原有的模型。你必須要意思到這個父工廠對於上面所有的事例因為它所有的地址對象成員都是不可變的(numbers, strings, etc.),與此同時這上面所有的事例工廠當你要深度復制對象裡面包含的對象時你都必須小心的使用。你必須也要知道一個小小的性能影響都來自於執行一個深度的克隆,但是我從來沒有看到過很明顯的問題。然而,如果你要深度的克隆一個大對象或者成千上萬的對象所有的立即復制,你將有可能做大量的性能分析。這將領導我們直接到下一個模式。

  為對象創建外觀

  在現實世界中,需求經常變化,JavaScript對象符號(或者說JSON)也是一樣,這些對象是由模型和集合所在的端點返回的。這或許會成為你的基礎代碼中的一個真正的大麻煩,如果你的視圖與底層的數據模型是緊耦合的話。因此,我為所有對象創建了getters和setters。

  支持這個模式的人非常多。如果任何底層的數據結構改變了,那麼視圖層並不需要更新許多;你將有一個數據的訪問點,所以你不太可能忘記做一個深度拷貝,你的代碼將會更易於維護更易於調試。負面因素在於這個模式可能導致模型或集合的一點點膨脹。

  我們看一個例子來闡明這個模式。想像我們有一個Hotel模型,包含有rooms和目前可獲得的rooms,而且我們希望可以通過床位大小來獲得rooms。

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 var Hotel = Backbone.Model.extend({ defaults: { "availa
copyright © 萬盛學電腦網 all rights reserved