7-14 backbone源碼

 1     _.extend = function(obj) {
 2         // each循環參數中的一個或多個對象
 3         each(slice.call(arguments, 1), function(source) {
 4             // 將對象中的所有屬性複製或覆蓋到obj對象
 5             for(var prop in source) {
 6                 obj[prop] = source[prop];
 7             }
 8         });
 9         return obj;
10     };

 

1:上面是underscore舊版本的extend方法代碼(和如今API調用方法不一樣),經我測試object.slice沒法使用,可是加入下面兩行就能夠slice.call(x,y)這樣調用了,可是依舊不能夠object.slice(undefined)。css

1     var ArrayProto = Array.prototype;
2     var slice = ArrayProto.slice;

 

2:現版本的extend方法html

 1   // Retrieve all the property names of an object.
 2   _.allKeys = function(obj) {
 3     if (!_.isObject(obj)) return [];
 4     var keys = [];
 5     for (var key in obj) keys.push(key);
 6     // Ahem, IE < 9.
 7     if (hasEnumBug) collectNonEnumProps(obj, keys);
 8     return keys;
 9   };
10 
11   _.extend = createAssigner(_.allKeys); 12 
13   var createAssigner = function(keysFunc, undefinedOnly) {
14     return function(obj) {
15       var length = arguments.length;
16       if (length < 2 || obj == null) return obj;
17       for (var index = 1; index < length; index++) {
18         var source = arguments[index],
19             keys = keysFunc(source),
20             l = keys.length;
21         for (var i = 0; i < l; i++) {
22           var key = keys[i];
23           if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
24         }
25       }
26       return obj;
27     };
28   };

 

3:JS精確整數最大值和判斷應該以數組仍是對象的方式進行迭代jquery

1   var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
2   var isArrayLike = function(collection) {
3     var length = collection != null && collection.length;
4     return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
5   };

 


1:模塊化開發,AMD數組

2:從backbone的整體結構來看,是一個當即執行的函數表達式,參數是一個匿名函數。(function(){})()和(function(){}())的目的是將函數聲明轉換爲函數表達式,消除Js引擎在識別函數聲明和函數表達式上的歧義,除了小括號外還有其餘運算符可以作到,詳細介紹能夠參照這篇文章:js中(function(){…})()當即執行函數寫法理解瀏覽器

1 (function(factory) {
2   //模塊定義
3 })(function(root, Backbone, _, $) {
4   //Backbone
5 });

 模塊處理內容以下:app

 1 function(factory) {
 2 
 3   // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
 4   // We use `self` instead of `window` for `WebWorker` support.
 5   //拿到當前環境中的全局對象;瀏覽器中爲window,self也是瀏覽器提供的一個全局對象,始終指向window
 6   //server端的運行環境則提供global這個全局對象
 7   var root = (typeof self == 'object' && self.self === self && self) ||
 8             (typeof global == 'object' && global.global === global && global);
 9 
10   // Set up Backbone appropriately for the environment. Start with AMD.
11   //若是有amd加載器則將Backbone定義包裝成amd加載器可識別的模塊
12   if (typeof define === 'function' && define.amd) {
13   //AMD規範定義兩個全局函數define和requrie,而且規定define有個amd屬性,來區分amd的define和普通名爲define的函數
14     define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
15       // Export global even in AMD case in case this script is loaded with
16       // others that may still expect a global Backbone.
17       root.Backbone = factory(root, exports, _, $);
18     });
19 
20   // Next for Node.js or CommonJS. jQuery may not be needed as a module.
21   //若是運行在Node端,則將Backbone包裝成CommonJs的模塊
22   } else if (typeof exports !== 'undefined') {
23     var _ = require('underscore'), $;
24     try { $ = require('jquery'); } catch (e) {}
25     factory(root, exports, _, $);
26 
27   // Finally, as a browser global.
28   //以上兩種狀況都沒有,則以最簡單的執行函數方式,將函數的返回值做爲全局對象Backbone
29   } else {
30     root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
31   }
32 
33 }

factory部分總體結構以下:模塊化

 1 function(root, Backbone, _, $) {
 2   // Backbone.Events
 3   // ---------------
 4 
 5   // Backbone.Model
 6   // --------------
 7 
 8   // Backbone.Collection
 9   // -------------------
10 
11   // Backbone.View
12   // -------------
13 
14   // Backbone.Router
15   // ---------------
16 
17   // Backbone.History
18   // ----------------
19 
20   // Helpers
21   // -------
22 }

Backbone的每一個部分都有本身的extend屬性,而且都有默認繼承的方法,參數只是對默認方法的覆蓋函數

 1 // Helper function to correctly set up the prototype chain for subclasses.
 2   // Similar to `goog.inherits`, but uses a hash of prototype properties and
 3   // class properties to be extended.
 4   //protoProps放置到子類原型上的屬性
 5   //staticProps模擬靜態屬性,直接放置到子類上
 6   var extend = function(protoProps, staticProps) {
 7     var parent = this;//利用局部變量保存this關鍵字
 8     var child;
 9 
10     // The constructor function for the new subclass is either defined by you
11     // (the "constructor" property in your `extend` definition), or defaulted
12     // by us to simply call the parent constructor.
13     //若是protoProps中有constructor屬性,則將constructor指向的函數做爲構造函數
14     if (protoProps && _.has(protoProps, 'constructor')) {
15       child = protoProps.constructor;
16     } else {//沒有構造函數,則利用一個默認的函數做爲構造函數。
17       //基本上屬於組合式繼承
18       child = function(){ return parent.apply(this, arguments); };
19     }
20 
21     // Add static properties to the constructor function, if supplied.
22     //underscore中的方法,與常見的mixin函數相似
23     _.extend(child, parent, staticProps);
24 
25     // Set the prototype chain to inherit from `parent`, without calling
26     // `parent`'s constructor function and add the prototype properties.
27     //將child的原型鏈與parent.prototype關聯。
28     //_.create函數,的做用相似Object.create,第一個參數是要被繼承的原型對象,第二個參數是要混入到新對象的鍵值對
29     child.prototype = _.create(parent.prototype, protoProps);
30     child.prototype.constructor = child;//原型中的constructor屬性指向child
31 
32     // Set a convenience property in case the parent's prototype is needed
33     // later.
34     child.__super__ = parent.prototype;//設置一個私有屬性指向父類的原型
35 
36     return child;
37   };
1   // Set up inheritance for the model, collection, router, view and history.
2   Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;

 

 

 


 

注意:具體model的屬性是在new的時候輸入的,extend的時候只是對實例進行一些方法和屬性的設置,好比default就是當new的時候不輸入的屬性的默認值!測試

 

葉小釵-初探Backboneui

 ①模型重點

當模型實例化時,他的initialize方法能夠接受任意實例參數,其工做原理是backbone模型自己就是構造函數,因此可使用new生成實例:

 

複製代碼
var User = Backbone.Model.extend({
    initialize: function (name) {
        this.set({name: name});
    }
});
var user = new User('刀狂劍癡');
assertEqual(user.get('name'), '刀狂劍癡');
複製代碼

 ②

constructor / initializenew Model([attributes], [options]) 
當建立model實例時,能夠傳入 屬性 (attributes)初始值,這些值會被 set (設置)到 model。 若是定義了 initialize 函數,該函數會在model建立後執行。

new Book({
  title: "One Thousand and One Nights",
  author: "Scheherazade"
});
相關文章
相關標籤/搜索