在上一章节中,咱们用vue实现了简单的todo应用,若是咱们把vue.js
引用去掉,首先是界面显示原始文本内容javascript
而后console报错html
index.html:22 Uncaught ReferenceError: Vue is not defined at index.html:22
缘由是咱们在代码中经过代码var app = new Vue({...})
建立了Vue对象,Vue对象是定义在vue.js中,如今没了vue.js天然报错。前端
这章的内容就是解决Vue对象找不到问题,让代码再也不报错,为何要先解决js报错问题而不是文本显示问题?由于Vue对象提供了Vue全部的功能,其中就包括值绑定,解决了值绑定的问题,界面天然也会恢复正常,因此先解决Vue对象找不到问题。vue
先解释什么是匿名函数,顾名思义就是没有定义名称的函数,好比下面这几种java
// 函数表达式 var fn = function add(a,b){ return a+b; } var c = fn(1,2); // 上面例子的结合 (function(a,b){return a+b;})(1,2); //事件响应函数 var button = document.getElementById('submitButton'); button.onclick = function(){ //do something }
还有其余状况,这里就不列举,java也有匿名类,跟js的匿名函数相似。jquery
再来聊一下前端面试必问,无数前端学子竟折腰的闭包是什么东西,这东西确实难理解,我以为很大一个缘由是翻译的问题,好比匿名函数,看名称大概就知道什么意思,闭包两个字没有任何想象的空间,并且还可能引发误会,闭包实际上跟包并无什么关系。个人不严谨但直观的理解是闭包就是类,你能够理解为闭包就是java里的类,在java类中,类能够定义变量和方法,方法能够引用类的变量,类比js,java类就是js的函数,java类变量就是js函数中定义的变量,java类的方法就是定义在js函数内部的函数。举个例子:面试
function CircleArea(r){ var PI=3.14159; function calculate(){ return PI*r*r; } return calculate; } var circle2=CircleArea(2); var area=circle2(); console.log(area);
正常当函数执行完变量会进行回收,在函数CircleArea
中返回了calculate
这个函数,理论上PI已经回收由于函数已经执行完,但在函数外部执行var area=circle2();
时,结果依然时正确的,说明PI并无被回收,这个就是闭包的特性,函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一块儿构成闭包(closure),这个才是官方对闭包的定义。vuex
那么在咱们这个应用中,Vue是以什么形式存在,对象仍是函数?毫无疑问确定是函数,只有在函数中才能实现复杂的逻辑,才能实现生命周期的控制。因此若是想让var app = new Vue({...})
这行代码不报错,一个可行的方案以下:api
var Vue = function (options){ console.log(options); }
建立一个js文件,名称就叫作vuex.js
,复制上面的代码到js文件中,将上一章html中引用vue.js的改成引用vuex.js,从新运行,这时候虽然界面仍是原样输出,可是console已经不报错了,并且也正确打印出数据。bash
这一章的目的也就达到了。能不能更优雅点?若是看过jquery源码和vue源码,你们都能在代码的开头看到这么一段代码
(function( global, factory ) {....})(this,function(options){...})
是否有点像上面匿名函数(function(a,b){return a+b;})(1,2);
,没错,这个就是当即执行的匿名函数,整个框架的逻辑就写在function中,配置经过options传入,这样写有什么好处?
其中保证拥有独立运行环境才是重要缘由,经过匿名函数实现了一个闭包,整个框架的逻辑在闭包中完成,经过function的return给调用者api。但若是经过匿名函数+闭包的方式,如何保证能new Vue({})
呢,能够全局声明Vue变量,将上面的代码修改成如下代码:
(function(global, factory) { global.Vue = factory })(this, function(options) { console.log(options); });
其中global
对象在调用时传入this
,this表示window对象,factory就是实现整个逻辑的匿名函数,经过global.Vue = factory
将匿名函数定义在window.Vue上,这样全局均可以使用new Vue
实现函数的调用。