闭包:指的是能够访问另一个函数作用域的变量的函数 递归函数:就是在函数体内调用本函数。使用递归函数一定要注意,处理不当就会进入死循环。递归函数只有在特定的情况下使用
闭包
使用函数自我调用实现闭包
var add = (function () {
var counter = 0;
return function () { return counter += 1; }
})();
add()
add();
add();
console.log(add());
**提升: **闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
直观的说就是形成一个不销毁的栈环境, 闭包实现了传递值和功能的调用
闭包点赞
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="js/Call.js" type="text/javascript" charset="utf-8"></script>
</head>
<style type="text/css">
#box ul {
width: 450px;
display: flex;
flex-direction: row;
justify-content: space-between;
list-style: none;
}
#box ul li {
display: flex;
flex-direction: column;
align-items: center;
height: 180px;
justify-content: space-between;
}
img {
width: 200px;
}
</style>
<body id="box">
<ul>
<li><img src="img/ly.jpg" /><input type="button" id="btn1" value="赞(1)" /></li>
<li><img src="img/lyml.jpg" /><input type="button" id="btn2" value="赞(1)" /></li>
</ul>
</body>
<script type="text/javascript">
function support() {
var value = 1;
return function () {
this.value = "赞(" + (++value) + ")";
}
}
var btnObj = document.getElementsByTagName("input")
for (var i = 0; i < btnObj.length; i++) {
btnObj[i].onclick = support();
}
</script>
</html>
递归
arguments.callee()
arguments.callee()可以调用自身函数
function geteverySum(x) {
if (x < 10) {
return x
}
return x % 10 + parseInt(arguments.callee(x / 10))
}
console.log(geteverySum(512)) //8
⚠️**注意: **函数中调用函数自己,此时就是递归,递归一定要有结束的条件
斐波那契数列
function getFbnq(x) {
if (x < 3) return 1
return getFbnq(x - 1) + getFbnq(x - 2)
}
console.log(getFbnq(12)) //144
计算数字每项相加的和
function geteverySum(x) {
if (x < 10) { return x; }
return x % 10 + parseInt(geteverySum(x / 10));
}
console.log(geteverySum(512)); //8
遍历DOM树
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>遍历DOM树</title>
</head>
<body>
<h1></h1>
</body>
</html>
<script>
function forDOM(root, fn) {
var children = root.children
for (var i = 0; i < children.length; i++) {
var child = children[i] //每个子节点
fn(child) //调用显示每个子节点的名字方法
child.children && forDOM(child, fn) //递归:有子节点,就继续的遍历
}
}
var root = document.documentElement //函数调用,传入html根节点
forDOM(root, function (node) {
console.log("节点的名字:" + node.nodeName)
})
</script>
递归深拷贝
var obj1 = {
age: 10,
car: ["奔驰", "宝马", "特斯拉", "奥拓"],
dog: { name: "大黄", age: 5, color: "黑白色" }
}
var obj2 = {}
function extend(a, b) {
for (var key in a) {
var item = a[key]
if (item instanceof Array) {
b[key] = []
extend(item, b[key])
}
else if (item instanceof Object) {
b[key] = {}
extend(item, b[key])
}
else {
b[key] = item
}
}
}
extend(obj1, obj2)
console.dir(obj1)
console.dir(obj2)
深拷贝就算拷贝的对象的数据(存放在堆里面的数据)变了,也不会影响到拷贝后的内容
浅拷贝 浅拷贝就是直接复制,就是把一个对象的地址给了另一个对象,他们指向的相同,两个对象之间有共同的属性或者方法
var obj1 = {
age: 10,
car: ["奔驰", "宝马", "特斯拉", "奥拓"]
}
var obj2 = {}
function extend(a, b) {
for (var key in a) {
b[key] = a[key]
}
}
extend(obj1, obj2)
obj2.car[0] = "保时捷"
console.dir(obj2)
console.dir(obj1)
/*
{ age: 10, car: ['保时捷', '宝马', '特斯拉', '奥拓'] }
{ age: 10, car: ['保时捷', '宝马', '特斯拉', '奥拓'] }
*/