模块化、闭包与当即执行函数的使用、MVC里的V和C

模块化、MVC里的V和C、闭包与当即执行函数的使用

这篇文章记录我写在线我的简历过程当中学习的知识
完整代码(暂未完成)
预览地址javascript

轮播Swiper组件的使用

英文官网html

中文网--Swiper4.x使用方法java

模块化

学习写代码的方法:
CRM
抄,运行,修改
P6R2AU.pnggit

模块化:把对应功能放到块里面,这个块能够是文件,或者div或者别的等等github

P6IEXd.png

当即执行函数的使用

将js分红不一样的几个模块后,而后使用文件引入,可是会出现问题:若是使用var 声明变量,那么就会成为全局变量,这样容易覆盖.面试

ES6以前,只有函数里面才有局部变量.
若是只用花括号包起来,那么在C++或者JAVA里面就是局部变量,可是JS里面会变量提高,提高到当前函数的最高地方,因此仍然是全局变量.segmentfault

因此若是想用局部变量,解决方法是把它放到一个函数中,而后当即执行,这样这个函数内部的变量就是局部变量.也不会被相同名字的全局变量覆盖.闭包

P6oiEq.png
不加感叹号就会语法错误,不会执行.因此得加一个感叹号,取反,就会运行后面的代码,执行后面的函数.虽然改变了返回值,可是咱们不须要返回值.因此改变了也无所谓mvc

因此接下来咱们将全部本身分离出来的单个js文件,都使用当即执行函数!function(){}.call()包起来模块化

这样才算真正的模块化,代码相互之间没有影响.
P6oZ2F.png

ps:
ES6模块

闭包的使用

下面的例子都使用当即执行函数隔离做用域
若是两个模块之间须要交流,例如在第一个模块上初始化,在第二个模块上使用

方法一:使用window

好比两个模块

module1.js和module2.js都被引入一个html文件里
PcP0PS.png

//module1.js
!function(){
    var person = window.person = {
        name:"frank",
    }
    //局部变量person和全局变量person用的是同一个地址
}.call()

虽然不一样变量,可是是一样的地址

//module2.js
!function(){
    var person = person;//即var person = window.person;
    console.log(person);
}.call();

这样不一样模块间就能够通讯,但这种方法很差.

方法二:使用闭包

始终不知道person的所有信息
,只能知道age的信息,且只能作一些它容许你操做的事情,这样module1就会对局部变量person有一个掌控.不会出现有人把person变成-1的状况,由于他访问不到age,他只能去GrowUp,除此以外没有能访问到的方法.

//module1.js
!function(){
    var person = {
        name:"mataotao",
        age:18,
    };
    window.mataotaoGrowUp = function(){
        person.age+=1;
        return person.age;
    };
}.call();
//module2.js
!function(){
    var newAge = window.mataotaoGrowUp();
    console.log(newAge);//19
}.call();

闭包在哪里?

若是一个函数访问了函数外的变量(mataotaoGrowUp()使用了person.age),那么 函数+函数外的变量,就是 闭包.

闭包做用:

  1. 用来 隐藏数据细节 (不告诉你多少岁可是你可让他涨一岁,隐藏了age 的细节和name)
  2. 能够用来 作访问控制 (只能访问到age,没法访问到name)

若是没有当即执行函数来模块化,那么这个闭包毫无心义,由于person直接使全局变量,全部的函数均可以访问到,而且修改也没法隐藏数据细节

PcPSH0.png

当即执行函数+闭包 实现对象细节的封装的方法

面试官会将上面的module1作以下修改(实际本质不变)

//module1.js
var accessor = function(){//这是一个返回了匿名函数的函数,accessor-访问器
    var person = {
        name:"mataotao",
        age:18,
    };
    return function(){
        person.age+=1;
        return person.age;
    };
}
var growUp = accessor();//执行accessor获得一个GrowUp函数
//growUp如今是一个全局变量了
growUp();

实际growUp()就至关于当即执行了,由于我声明了一个函数,并且当即执行了

这就是闭包

MVC的V和C

MVC的前提就是 模块化
P6IKtf.png

View就是能看到的东西

例如在
<script src="./js/init_Swiper.js"></script><!-- 初始化Swiper>标签 -->这个模块中咱们初始化了一个Swiper

PciCqI.png
这个而且对.swiper-container这个div进行操做,.swiper-container这个div就是 VIEW(用户能够看到的东西).

对于轮播组件来讲,这一部分就是他的view部分
PciiZt.png

这个div就是init-swiper这个模块的view.

明白这个以后咱们将view单独分离出来

分离view

咱们修改代码,单独将view分离,例如轮播图的view:
PcFM1e.png

PcFDns.png

也将剩下的几个js模块进行修改

例如<script src="./js/sticky-navbar.js"></script>

PcF6A0.png

view就是要告诉js,html中的哪一块是我要操做的东西

PcFhjJ.png

Controller就是控制View的方法

MVC中的C用来控制/操做view

以topNavBar为例
PcFjjH.png
将要作的操做写成controller函数,并把要操做的view当作参数传进去,实现对view的控制/操做

进一步的改进:

PcEAmj.png

须要注意:

  1. 对象的函数里的this,就是对象自己controller.init(view);//至关于controller.init.call(controller,view);//this就是当前对象
  2. this.bindEvents();//至关于this.bindEventS.call(this),这里的this就是init函数里call的controller,因此这个this是转过来了,也是对象自己

继续优化,分离代码

若是咱们要作其余的事情,好比把激活和不激活这个导航分离,不要写在bindEvents里了,继续在对象里添加操做的函数
PcV0P0.png
bind(this)后,就是把controller绑定到这个函数的this上,把这个函数的this由window变成controller,以后this.active();this.deactive();这两个this 就变成了controller了

bind方法用于将函数体内的 this绑定到某个对象,而后返回一个新函数。
bind()使用方法

这里的bind()就是将函数体内的this绑定到了controller,函数体内的this就是controller了

若是不用bind()也能够用箭头函数()=>{},箭头函数自己是没有this的.因此若是在箭头函数用this,那么就是箭头函数外面的离它最近的this!
PceR9x.png

最终stick-navBar的代码:
PcmvJ1.png

对轮播的js模块使用controller进行优化

原本:
PcnCLD.png
修改后:
PcnNlV.png
修改以后的先后对比
结构很是清晰有条理,将整个要作的事层次分明得分为几个部分

对当页跳转的缓动动画也进行controller的优化

下面是当页跳转的缓动动画修改后的代码:
Pc8uZV.png

总结

这样代码就不会显得混乱了,controller对view的操做被有条理地分开,有初始化view,绑定view事件,激活这个view,不激活这个view等等对view的操做
controller全部的属性就是对view的全部操做!!!这就是mvc里的c的意义

相关文章
相关标签/搜索