zoukankan      html  css  js  c++  java
  • 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)。

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

    2:现版本的extend方法

     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精确整数最大值和判断应该以数组还是对象的方式进行迭代

    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 });

     模块处理内容如下:

     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的时候不输入的属性的默认值!

     

    叶小钗-初探Backbone

     ①模型重点

    当模型实例化时,他的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"
    });



  • 相关阅读:
    链串
    一个外行谈行业应用的营销问题
    SharePoint 2013的100个新功能之场管理
    Deep Learning and Shallow Learning
    [IOS]UIWebView 请求网络页面或者加载本地资源页面
    九度OJ 打印日期 (模拟)
    STM32学习之路-SysTick的应用(时间延迟)
    box-shadow
    让算法会说话之高速排序
    A5-1和DES两个加密算法的学习
  • 原文地址:https://www.cnblogs.com/cndotabestdota/p/5669418.html
Copyright © 2011-2022 走看看