学习闭包以及递归之前,了解到一个知识点:严格模式!它又是什么呢,为我们在写代码的时候处于什么作用呢,一起来看看吧!
一、严格模式
1.什么是严格模式
JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式,即在严格的条件下运行 JS 代码。
严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。
严格模式对正常的 JavaScript 语义做了一些更改: 1.消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。 2.消除代码运行的一些不安全之处,保证代码运行的安全。 3.提高编译器效率,增加运行速度。 4.禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名
2.开启严格模式
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。
(1)为脚本开启严格模式
有的 script 脚本是严格模式,有的 script 脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他
script 脚本文件:
(function (){
"use strict";
var num = 10;
function fn() {}
})();
<script>
"use strict";
</script>
<script>
</script>
(2)为函数开启严格模式
要给某个函数开启严格模式,需要把“use strict”; (或 ‘use strict’; ) 声明放在函数体所有语句之前
function fn(){
"use strict";
return "123";
}
使用了严格模式,对 Javascript 的语法和行为,都做了一些改变。
'use strict'
num = 10
console.log(num)
--------------------------------------------------------------------------------
var num2 = 1;
delete num2;
--------------------------------------------------------------------------------
function fn() {
console.log(this);
}
fn();
---------------------------------------------------------------------------------
function Star() {
this.sex = '男';
}
var ldh = new Star();
console.log(ldh.sex);
----------------------------------------------------------------------------------
setTimeout(function() {
console.log(this);
}, 2000);
更多严格模式要求参考
二、闭包
首先复习一下变量的作用域
变量根据作用域的不同分为两种:全局变量和局部变量。
- 函数内部可以使用全局变量。
- 函数外部不可以使用局部变量。
- 当函数执行完毕,本作用域内的局部变量会销毁。
1.什么是闭包
闭包(closure)指有权访问另一个函数作用域中变量的函数。简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。
2.闭包的作用
闭包有三个特性: ①函数嵌套函数 ②函数内部可以引用函数外部的参数和变量 ③参数和变量不会被垃圾回收机制回收
作用:延伸变量的作用范围。
function fn() {
var num = 10;
function fun() {
console.log(num);
}
return fun;
}
var f = fn();
f();
我们通过案例来深入了解一下闭包: 1.利用闭包的方式得到当前li 的索引号
<body>
<ul class="nav">
<li>榴莲</li>
<li>臭豆腐</li>
<li>鲱鱼罐头</li>
<li>大猪蹄子</li>
</ul>
<script>
var lis = document.querySelector('.nav').querySelectorAll('li')
for (var i = 0; i < lis.length; i++) {
lis[i].index = i
lis[i].onclick = function() {
console.log(this.index);
}
}
for (var i = 0; i < lis.length; i++) {
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i)
}
</script>
</body>
2.闭包应用-计算打车价格
<script>
var car = (function() {
var start = 13
var total = 0
return {
price: function(n) {
if (n <= 3) {
total = start
} else {
total = start + (n - 3) * 5
}
return total
},
yd: function(flag) {
return flag ? total + 10 : total
}
}
})()
console.log(car.price(5));
console.log(car.yd(true));
</script>
三、递归
1.什么是递归
递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数
注意:递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。
2.递归的特点
1.每一级函数调用时都有自己的变量,但是函数代码并不会得到复制,如计算5的阶乘时每递推一次变量都不同; 2.每次调用都会有一次返回,如计算5的阶乘时每递推一次都返回进行下一次; 3.递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序; 4.递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反; 5.递归函数中必须有终止语句。
案例: 1.利用递归求1~n的阶乘
function fn(n) {
if (n == 1) {
return 1
}
return n * fn(n - 1)
}
console.log(fn(3));
2.利用递归求斐波那契数列
function fb(n) {
if (n === 1 || n === 2) {
return 1;
}
return fb(n - 1) + fb(n - 2);
}
console.log(fb(3));
3.利用递归遍历数据
var data = [{
id: 1,
name: '家电',
goods: [{
id: 11,
gname: '冰箱',
goods: [{
id: 111,
gname: '海尔'
}, {
id: 112,
gname: '美的'
},
]
}, {
id: 12,
gname: '洗衣机'
}]
}, {
id: 2,
name: '服饰'
}];
function getID(json, id) {
var o = {};
json.forEach(function(item) {
if (item.id == id) {
o = item;
return o;
} else if (item.goods && item.goods.length > 0) {
o = getID(item.goods, id);
}
});
return o;
}
|