在上一章节中,咱们用 vue 实现了简略的 todo 利用,如果咱们把 vue.js
援用去掉,首先是界面显示原始文本内容
而后 console 报错
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 对象找不到问题。
匿名函数和闭包
先解释什么是匿名函数,顾名思义就是没有定义名称的函数,比方上面这几种
// 函数表达式
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 的匿名函数相似。
再来聊一下前端面试必问,有数前端学子竟折腰的闭包是什么货色,这货色的确难了解,我感觉很大一个起因是翻译的问题,比方匿名函数,看名称大略就晓得什么意思,闭包两个字没有任何设想的空间,而且还可能引起误会,闭包实际上跟包并没有什么关系。我的不谨严但直观的了解是 闭包就是类,你能够了解为闭包就是 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),这个才是官网对闭包的定义。
那么在咱们这个利用中,Vue 是以什么模式存在,对象还是函数?毫无疑问必定是函数,只有在函数中能力实现简单的逻辑,能力实现生命周期的管制。所以如果想让 var app = new Vue({...})
这行代码不报错,一个可行的计划如下:
var Vue = function (options){console.log(options);
}
创立一个 js 文件,名称就叫做vuex.js
, 复制下面的代码到 js 文件中,将上一章 html 中援用 vue.js 的改为援用 vuex.js,从新运行,这时候尽管界面还是原样输入,然而 console 曾经不报错了,而且也正确打印出数据。
这一章的目标也就达到了。能不能更优雅点?如果看过 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
实现函数的调用。
参考
- 模拟 vue 本人入手写响应式框架(一) – Vue 实现 todo 利用
- 模拟 vue 本人入手写响应式框架(二) – Vue 对象创立