<script>
//1.求1-n之间的累加和
function getSum(n){
//递归 : 自己调用自己
return n == 1? 1 : getSum(n-1) + n;
// if(n == 1){
// return 1;
// }else{
// return getSum(n-1) + n;
// };
};
var num1 = getSum(100);
console.log(num1);
//2.求阶乘
var res = (function(n){return n==1?1:n*arguments.callee(n-1)})(6);
console.log(res);
function getJieChen(n){
//递归实现
return n == 1?1:n*getJieChen(n-1);
// if(n == 1){
// return 1;
// }else{
// return n * getJieChen(n-1);
// };
// if(n == 1){
// return 1;
// }else if(n == 2){
// return 2 * getJieChen(1)
// }else if(n == 3){
// return 3 * getJieChen(2)
// }
// ………………
// else if(n == n){
// return n * getJieChen(n-1)
// };
//使用循环思路
// var sum = 1;
// for(var i = 1;i<=n;i++){
// sum *= i;
// };
// return sum;
};
var n1 = getJieChen(5);
console.log(n1);
//3.求斐波那契额数列
//1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597
function getFeiBo(n){
//使用递归实现
// if(n == 1 || n == 2){
// return 1;
// }else{
// return getFeiBo(n-1) + getFeiBo(n-2);
// };
// if(n == 1 || n == 2){
// return 1;
// }else if(n == 3){
// return getFeiBo(2) + getFeiBo(1)
// }else if(n == 4){
// return getFeiBo(3) + getFeiBo(2)
// }
// ……………………
// else if(n == n){
// return getFeiBo(n-1) + getFeiBo(n-2);
// };
//数组+循环实现
var arr = [1,1];
for(var i = 2;i<n;i++){
arr[i] = arr[i-1] + arr[i-2];
};
console.log(arr);
return arr[arr.length-1];
};
var res = getFeiBo(2000);
console.log(res);
</script>
<div id="box">一级
<div>1
<div>11
<p>111
<b>1111</b>
<b>2222</b>
</p>
<p>112
<b>1112</b>
<b>111222</b>
</p>
</div>
</div>
<div>2
<p>我是pp
<b>我是bb</b>
</p>
</div>
<p>3
<p>我爱你</p>
<p>一万年
<b>这不是真的</b>
</p>
</p>
</div>
<script>
/*
遍历DOM树 :获取某个元素所有的后代元素
1.以前学的的webapi,有没有直接的方法可以获取呢?
没有。 元素.children 只能获取子元素
2.写一个函数: 获取某个元素的子元素,子元素又有子元素,又可以继续调用这个函数
获取子元素的子元素,以此类推形成递归调用
*/
function getHouDai(ele){
for(var i = 0;i<ele.children.length;i++){
arr.push(ele.children[i]);
//ele的子元素也有可能有自己的子元素,继续调用函数获取子元素的子元素
getHouDai(ele.children[i]);
};
};
// var arr = [];//声明数组存储所有的后代元素
// var box = document.getElementById('box');
// getHouDai(box);
// console.log(arr);
var arr = [];
getHouDai(document);//遍历文档树
console.log(arr);
</script>
是
一个可以获取其他函数内部变量的函数
问题:如何在函数外部访问函数内部的变量?
1.直接获取
//1.直接在外部是获取不到函数内部的变量的
function fn(){
var person = {
name:"老八",
age:28
}
}
fn();
//函数外部无法直接获取函数内部的变量
console.log(person);//报错person is not defined
2.通过函数返回值return
//2.使用函数返回值:return(有一定的内存资源浪费)
// 两次获取的不是同一个对象,无法实现需求
function fn() {
var person = {
name: "老八",
age: 28
}
return person;
}
var p1 = fn();
console.log(p1);
var p2 = fn();
console.log(p2);
//这两次获取的person是同一个吗?
//不是同一个,fn函数每调用一次,就会在堆中开辟空间,虽然数据一样但是两个地址不同
console.log(p1 == p2); //false
3.使用闭包
/*
1.闭包是什么:闭包是一个函数
2.闭包的作用:函数外面 访问函数内部变量(局部变量)
3.闭包语法:闭包语法有很多种写法,但是一般分为三个环节
a.在外部函数中 声明一个闭包函数(闭包函数可以访问1级链中的局部变量)
b.在闭包函数中 返回你想要访问的局部变量
c.在外部函数中 返回这个闭包函数
闭包函数:沟通全局作用域与局部作用域的一座桥梁
*/
function fn() {
var person = {
name: "老八",
age: 28
}
//1.在外部函数中声明一个内部函数(闭包函数)
function closure(){
//2.在闭包函数中 返回你想要获取的局部变量
return person;
}
//3.在外部函数中 返回这个闭包函数
return closure;
}
//调用外部函数fn:返回闭包函数closure的地址被bibao变量接受
var bibao1 = fn();
// var bibao2 = fn();
var p1 = bibao1();
console.log(p1);
var p2 = bibao1();
console.log(p2);
console.log(p1 == p2); //true
<script>
/*
1.闭包语法
a.在外部函数中 : 声明闭包函数
b.在闭包函数中: 返回你想要访问的变量
c.在外部函数中 : 返回闭包函数
2.闭包语法注意点
如果希望得到同一个变量 : 外部函数只调用一次,闭包函数可以调用多次
如果希望得到不同变量 : 外部函数调用多次,闭包函数只调用一次
*/
function outer(){
var num = Math.ceil(Math.random()*100);
//1.声明闭包函数
function closure(){
//2.返回你想要访问的变量
return num;
};
//3.返回这个闭包函数
return closure;
};
//(1)得到的是同一个数据 : 外部函数只调用一次,闭包函数调用多次
var bibao = outer();
var num1 = bibao();
var num2 = bibao();
var num3 = bibao();
console.log(num1,num2,num3);
//(2)得到的是不同数据 : 外部函数调用多次,闭包函数调用一次
// var bibao1 = outer();
// var n1 = bibao1();
var n1 = outer()();
// var bibao2 = outer();
// var n2 = bibao2();
var n2 = outer()()
// var bibao3 = outer();
// var n3 = bibao3();
var n3 = outer()();
console.log(n1,n2,n3);
了解了闭包之后做一道测试题:
for (var i =1;i<=3;i++){
function outer ( ) {
var num = i;
function closure ( ) {
return num;
};
return closure;
};
console.log ('循环内:' + outer () () );//会打印什么
};
console.log ('循环外' + outer () () )//会打印什么
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
//需求:点击显示按钮索引
//获取按钮
var btnList= document.querySelectorAll("button");
// for(var i=0;i<btnList.length;i++){
// function outer(){
// var num =i;
// //1 声明闭包函数
// function closure(){
// console.log(num);
// }
// return closure;
// }
// var bibao = outer();
// btnList[i].onclick = bibao;
// }
//高级写法
for(var i=0;i<btnList.length;i++){
(function(i){
btnList[i].onclick = function(){
console.log(i);
}
})(i)
}
</script>
<script>
//循环中的定时器
//需求: 开启三个定时器,每隔1s分别打印1 2 3
for (var i = 1; i <= 3; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
};
//使用循环解决代码冗余问题
/*
定时器中的函数类似于事件处理函数,不会立即执行。而是等页面加载完毕,
等待1s后执行。此时循环早已执行结束,i全局变量的值变成4
*/
// for (var i = 1; i <= 3; i++) {
// function outer() {
// var num = i;
// return function() {
// setTimeout(function () {
// console.log(num);
// }, 1000);
// };
// }
// outer()();
// };
//简化后
for (var i = 1; i <= 3; i++) {
setTimeout(function (num) {
return function () {
console.log(num);
}
}(i), 1000);
};
</script>
//3.使用闭包:
//优点:计算次数少于递归,数组存储元素少于以前做法
/*核心思路
* 1.数组中只存储三个元素:前两个元素用于存储前两列数字,第三个元素用于占位,存储最后的结果
* 2.如何避免数组被重复声明:使用闭包延长数组声明周期
*/
function feiBo() {
var arr = [1, 1, 0];
//使用闭包
//1. 声明闭包函数
function closure(n){
for (var i = 2; i < n; i++) {
arr[2] = arr[0] + arr[1];
arr[0] = arr[1];
arr[1] = arr[2];
};
console.log(arr);
//2. 返回想要访问的局部变量
return arr[2];
};
//3.返回闭包函数
return closure;
};
var bibao = feiBo();
var res = bibao(15);
console.log(res);//610
<script>
//1.
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name;
};
}
};
//object.getNameFunc():返回一个匿名函数,在全局作用域中调用该函数,此时相当于是window调用,所以this指向window
console.log(object.getNameFunc()()); //"The Window"
//2.
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
var that = this;
return function () {
return that.name;
};
}
};
//object.getNameFunc():在getNameFunc函数中,this指向object,使用局部变量that来存储this,所以闭包函数中that指向的是object
console.log(object.getNameFunc()()); // "My Object"
</script>
沙箱:是js一种设计模式,指的是一种封闭的空间,通常是一个自执行函数
<script>
/*
1.沙箱模式 :是js的一种设计模式(思想),是一个封闭的内存空间.通常是一个匿名函数自调用
2.沙箱模式好处
a. 封闭的内存空间(不会存在全局变量污染)
b. 模块化开发
3.沙箱模式也是闭包的应用场景
*/
(function (w){
//独立作用域
var person = {};
person.sayHi = function(){
};
person.name = '111';
person.eat = function(){
};
//将局部变量person动态赋值给window的属性
/*不会在沙箱内部访问全局变量
1.破坏封装性
2.避免代码压缩错误 (以后开发代码会压缩成一行,去掉空格,会复杂英文简写)
*/
w.person = person;
})(window);
console.log(person);//window.person
</script>
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。