暴力分析backbone.js(2)
继续上一节内容,带着疑问和简单的Dome来分析backbone.js。
这次我把简单Dome Copy到本地,引入backbone.js库。(这里我就不引入其他库了,麻烦,所以要简单修改一下!)
1 <body> 2 <script src="backbone.js"></script> 3 <script> 4 (function(doc){ 5 6 var ListView = Backbone.View.extend({ 7 el: doc.getElementsByTagName('body'), 8 9 initialize: function(){ 10 _.bindAll(this, 'render'); 11 12 this.render(); 13 }, 14 15 render: function(){ 16 var ListUl = doc.createElement('ul'); 17 ListUl.innerHTML = '<li>hello world</li>'; 18 this.el.appendChild(ListUl); 19 } 20 }); 21 22 var listView = new ListView(); 23 })(document); 24 </script> 25 </body>
然后打开网页,报错了!!!从错误开始着手!!!
点击backbone.js:224 定位报错位置
断点了一下,这种写法,_ 其实是一个对象,each属于_对象的一个方法,我们打印了一下,发现为undefined,继续往上面排查。
会发现_对象是函数的传参,因为没传进来,所以是undefined,所以现在我们继续找,看哪里执行这个函数!
在这之前我们先来看一下backbone的外壳。一个自执行函数,参数root、factory,分别对应 this 、 func()。不难发现this指向的就是 window,然而我们要找的是在哪里执行了func(),func()作为参数赋给了形参factory,也就是说我们要在这个自执行函数内寻找调用factiory的位置,看factiory的4个参数传对了没有?
1 (function (root, factory) { 2 3 }(this, function () { 4 /***/ 5 }))
自执行函数内是if语句,我给每个if语句的开始加了断点 debugger,看就引用了backbone是执行哪个?结果是执行了 最后一个,然后往上看一下2个条件:
1.typeof define === 'function' && define.amd
2.typeof exports !== 'undefined'
如果你细心的看注释不难发现define 和 exports是2个依赖库,如果它们都有引用,那么 define的优先级最高。就算不看注释,细心看,你会发现原生根本没这2个东西,百度搜一下就知道了,如果你如果你用过就跟不用说了。
我什么都没引用走的就是优先级最低的咯。
继续走下去,还是断点。
root === window
root._ === ??? window下面没有这个对象啊!(怎么办,回头看一下别人dome引用的库,除了jQuery之外还有underscore 和 json2)
在看func()的形参$ 对应的是这样一串表达式 (root.jQuery || root.Zepto || root.ender || root.$),也就是说backbone必须要有依赖库,这句表达式的意思就是,window.jQuery有的话,就引用window.jQuery,依次类推,全部没有就是undefined,什么库都不要引用直接执行这句表达式试试看。
所以走最后一条路,backbone所依赖的 jQuery 和 undercore 是必不可少的,老老实实把它们引用进来吧
1 (function(root, factory) { 2 3 if (typeof define === 'function' && define.amd) { 4 debugger; 5 define(['underscore', 'jquery', 'exports'], function(_, $, exports) { 6 root.Backbone = factory(root, exports, _, $); 7 }); 8 9 } else if (typeof exports !== 'undefined') { 10 debugger; 11 var _ = require('underscore'); 12 factory(root, exports, _); 13 14 } else { 15 debugger; 16 root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$)); 17 } 18 19 }(this,function(root, Backbone, _, $){ 20 /**/ 21 })
振奋人心的时候来了,果然跑通了!!!
解决了问题,先休息一下,在继续分析backbone!