模块化、闭包与立即执行函数的使用、MVC里的V和C
模块化、MVC里的V和C、闭包与立即执行函数的使用
这篇文章记录我写在线个人简历过程中学习的知识 完整代码(暂未完成) 预览地址
轮播Swiper组件的使用
模块化
学习写代码的方法: CRM 抄,运行,修改
模块化:把对应功能放到块里面,这个块可以是文件,或者div或者别的等等
立即执行函数的使用
将js分成不同的几个模块后,然后使用文件引入,但是会出现问题:如果使用var
声明变量,那么就会成为全局变量,这样容易覆盖.
在ES6之前,只有函数里面才有局部变量. 如果只用花括号包起来,那么在C++或者JAVA里面就是局部变量,但是JS里面会变量提升,提升到当前函数的最高地方,所以仍然是全局变量.
所以如果想用局部变量,解决方法是把它放到一个函数中,然后立即执行,这样这个函数内部的变量就是局部变量.也不会被相同名字的全局变量覆盖.
不加感叹号就会语法错误,不会执行.所以得加一个感叹号,取反,就会运行后面的代码,执行后面的函数.虽然改变了返回值,但是我们不需要返回值.所以改变了也无所谓
所以接下来我们将所有自己分离出来的单个js文件,都使用立即执行函数!function(){}.call()
包起来
这样才算真正的模块化,代码相互之间没有影响.
ps: ES6模块
闭包的使用
下面的例子都使用立即执行函数隔离作用域 如果两个模块之间需要交流,例如在第一个模块上初始化,在第二个模块上使用
方法一:使用window
比如两个模块
module1.js和module2.js都被引入一个html文件里
//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
),那么 函数+函数外的变量,就是 闭包.
闭包作用:
- 用来 隐藏数据细节 (不告诉你多少岁但是你可以让他涨一岁,隐藏了age 的细节和name)
- 可以用来 做访问控制 (只能访问到age,无法访问到name)
如果没有立即执行函数来模块化,那么这个闭包毫无意义,因为person直接使全局变量,所有的函数都可以访问到,并且修改也无法隐藏数据细节
立即执行函数+闭包 实现对象细节的封装的方法
面试官会将上面的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的前提就是 模块化
View就是能看到的东西
例如在
<script src="./js/init_Swiper.js"></script><!-- 初始化Swiper>标签 -->
这个模块中我们初始化了一个Swiper
这个并且对.swiper-container
这个div进行操作,.swiper-container
这个div就是 VIEW(用户可以看到的东西).
对于轮播组件来说,这一部分就是他的view部分
这个div就是init-swiper这个模块的view.
明白这个之后我们将view单独分离出来
分离view
我们修改代码,单独将view分离,例如轮播图的view:
也将剩下的几个js模块进行修改
例如<script src="./js/sticky-navbar.js"></script>
view就是要告诉js,html中的哪一块是我要操作的东西
Controller就是控制View的方法
MVC中的C用来控制/操作view
以topNavBar为例
将要做的操作写成controller函数,并把要操作的view当做参数传进去,实现对view的控制/操作
进一步的改进:
需要注意:
- 对象的函数里的this,就是对象本身`controller.init(view); //相当于controller.init.call(controller,view);//this就是当前对象`
`this.bindEvents();
//相当于this.bindEventS.call(this)`,这里的this就是init函数里call的controller,所以这个this是转过来了,也是对象本身
继续优化,分离代码
如果我们要做其他的事情,比如把激活和不激活这个导航分离,不要写在bindEvents里了,继续在对象里添加操作的函数
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
!
最终stick-navBar的代码:
对轮播的js模块使用controller进行优化
本来:
修改后:
修改之后的前后对比 结构非常清晰有条理,将整个要做的事井井有条得分为几个部分
对当页跳转的缓动动画也进行controller的优化
下面是当页跳转的缓动动画修改后的代码:
总结
这样代码就不会显得混乱了,controller对view的操作被有条理地分开,有初始化view,绑定view事件,激活这个view,不激活这个view等等对view的操作 controller所有的属性就是对view的所有操作!!! 这就是mvc里的c的意义
- 独家 | 一文读懂TensorFlow(附代码、学习资料)
- 解决openssh漏洞,升级openssh版本
- 解决NTPD漏洞,升级Ntpd版本
- 独家 | 手把手教TensorFlow(附代码)
- HBase Region自动切分细节
- eclipse搭建ssh后台
- 解决mysql漏洞 Oracle MySQL Server远程安全漏洞(CVE-2015-0411)
- im4java包处理图片
- centOS7 mini配置linux服务器(五) 安装和配置tomcat和mysql
- RedisPool操作Redis,工具类实例
- centOS7 mini配置linux服务器(四) 配置jdk
- 老司机教你“飙”EventBus3
- Android listView异步下载和convertView复用产生的错位问题
- 实用Android 屏幕适配方案分享
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 华为提出十大数学挑战!解出一个就是年薪百万!
- 一道 Google 的面试题
- 生产实践 | 基于 Flink 的短视频生产消费监控
- 图数据库调研
- Swift 类构造器的使用
- 「网络IO套路」当时就靠它追到女友
- 起个简单枯燥的标题:找出连续差相同的数字
- 10分钟带你搞懂代理模式、静态代理、JDK+CGLIB动态代理
- 握草!某程序员竟然在深夜偷偷在代码里下毒!
- 自然资源部贡献的Landuse数据(2000、2010、2020)
- LoRa节点开发——SDK整体设计思路
- 01 . Nginx简介及部署
- 02 . Nginx平滑升级和虚拟主机
- LoRa节点开发——LoRaWAN节点入网代码详解
- 03 . Nginx日志配置及日志切割