全局 函数 递归 指针 局部变量 环境污染 内聚 传递 递归 准则
一,立即执行函数 --- IIFE
立即执行函数的集中表现形式:
立即执行函数的特点:
二,JS 全局污染
为什么会造成全局污染?
JS 没有块级作用域,在函数外定义的变量,均为全局变量;
全局变量过多会削弱程序的灵活性,增大了模块之间的耦合度,多人协作开发会导致变量冲突,造成环境污染.
耦合度:即模块之间的依赖关系:控制关系,调用关系,数据传递关系;
划分模块准则:高内聚低耦合
如何解决全局污染?
1. 命名空间
2. 立即执行函数(里面创建的变量,为局部变量)
三,闭包
(function(){})()
(function(){}())
!function(){}()
var fn = function(){} ()
1. 闭包的概念
广义闭包:函数内部声明变量,函数外部无法访问到,模拟块级作用域,即生成闭包
JS 中所有函数,都能形成一个闭包
狭义闭包:闭包模型(一个函数,作为另一个函数的返回值)
闭包实际上由两部分组成:
函数体:函数的代码
函数所处的环境:作用域链
综上:把函数体 及 函数所处的环境,成为闭包
2. 主线:函数 不管在哪个环境下调用,都要回到创建函数的环境下执行
3. 闭包作用:
解决全局污染
对函数内的变量,起保护作用;除了返回函数外,没有任何办法可以访问到函数内的变量
4. 经典闭包模型
可简单理解为,一个函数作为另一个函数的返回值;这样就有了内层函数,和外层函数;
外层函数中:定义变量(对变量起保护作用)
返回值返回的 内层函数:定义操作变量的方法
闭包模型如下:
4. 闭包弊端(内存泄露)---> 解决:内层函数 = null
<script>
var fn = function() {
var num = 10;
return {
f1: function() {}
f2: function() {}
}
};
var temp = fn();
// 调用 f1 ,f2 方法
temp.f1();
temp.f2();
</script>
闭包中外层函数定义的变量一直存在,不会被自动释放掉;
因为内层函数一直引用着 外层函数中定义的变量;并且内层函数每一次操作变量,都是在外层函数中变量基础上进行操作的
手动释放内存占用:内层函数 = null
四,沙箱(闭包的一种体现形式)
1. 沙箱模式
函数自调用
给 window 注册属性 或 return 变量
经典沙箱模式如下:
window.main = main; 或 return main;
<script>
(function(window) {
// 定义变量,及一些列js逻辑
var main = '';
jQuery 中运用沙箱模式,如下:
})(window)
</script>
2. 沙箱的作用:
(function() {
window.jQuery = window.$ = jQuery;
return jQuery;
})();
变量隔离,保护变量(沙箱内定义的变量,沙箱外不能访问到)
避免全局污染
3. IIFE 立即执行函数
五,函数 递归
(function(){})()
(function(){}())
!function(){}()
var fn = function(){} ()
1. 简单理解递归:函数自己 ---> 调用自己
2. 何时用递归:函数需要多次调用自己,自己嵌套自己
3. 如何书写 递归函数(3 点)?
划归思想:找出规律,总结前者 , 后者之间的关系
临界条件:找出临界值,停止递归
retrun 自己函数的调用
4. 递归相关算法实现:
递归实现兔子数列(菲波那切数列)
菲波那切数列 优化【缓存】
<script>
function fn3(m) {
if (m === 1 || m === 2) {
return 1;
}
return fn3(m - 1) + fn3(m - 2);
}
console.log(fn3(20));
</script>
递归:阶乘
<script>
var cache = {};
function fn4(m) {
if (cache[m]) {
return cache[m];
}
if (m === 1 || m === 2) {
cache[m] = 1;
return 1;
} else {
return cache[m] = fn4(m - 1) + fn4(m - 2);
}
}
console.log(fn4(200));
</script>
递归:次方
<script>
function fn2(m) {
if (m <= 1) {
return 1;
}
return fn2(m - 1) * m;
}
console.log(fn2(3));
</script>
5. 严格模式下,递归 ---> 健壮代码
<script>
function fn1(m, n) {
if (n === 0) {
return 1;
}
return fn1(m, n - 1) * m;
}
console.log(fn1(2, 4));
</script>
非严格模式下,简易递归
非严格模式下,健壮递归
<script>
var fn = function(m) {
if (m <= 1) {
return 1;
}
return fn(m - 1) * m;
}
var fn1 = fn;
fn = null;
console.log(fn1(3)); // 报错
</script>
arguments.callee 指向一个正在执行的函数的指针
严格模式下,不允许用 arguments.callee, 健壮代码如下:
<script>
var fn = function(m) {
if (m <= 1) {
return 1;
}
return arguments.callee(m - 1) * m;
}
var fn1 = fn;
fn = null;
console.log(fn1(3)); // 6
</script>
JS 函数的应用 --- 立即执行函数,全局污染,闭包,沙箱,递归
<script>
var fn1 = function fn(m) {
if (m <= 1) {
return 1;
}
return fn(m - 1) * m;
}
var fn2 = fn1;
fn1 = null;
console.log(fn2(3));
</script>
来源: http://www.bubuko.com/infodetail-2457283.html