JS递归,斐波那契数,slice,闭包,面试题,setInterval,clearInterval【诗书画唱】
概括:
个人对闭包的理解
面试题的第5题
老师的答案
我的答案
作业和面试题
课上老师写的代码
课堂跟敲笔记1.html
面试题个人解析
setInterval
clearInterval
//闭包:在一个函数中定义另外一个函数
//闭包的特点:内部函数可以访问外部函数中定义的变量
//每调用一次外部的函数,就会产生一个独立的闭包(变量环境)
//如果内部函数中定义了一个变量跟外部函数中的变量同名,
//那么内部函数的变量值会覆盖掉外部函数的变量值
//解决重名变量的冲突
//实现封装
//求前n个自然数的和
//初始条件
//递推公式
//求前n个自然数的乘积
//obj是js对象
//props是数组
//slice方法从指定的数组中截取数组产生一个新的数组
//slice(1)表示从下标1的元素开始,保留后面的所有元素组成一个新的数组
递归面试题
面试题中要补全的代码
个人解析:
else中最终表达式执行的最终结果
包括if或包括else if中写自己要定义的函数的格式的常量可知值表达式就可以
该题中的getValue(obj[props[0]],props.slice(1))是最终的表达式。
执行最终的表达式,使用(被)赋值法,obj被赋值为obj[props[0]],
"props"(这里我把双引号中的内容表示为会被赋值的可变部分
双引号在这里仅仅是我的标记,方便读者等等看懂我的意思)被赋值为props.slice(1),
最终 if("props".length-1==0)
中"props".length-1的值会为0,return obj[props[0]];这个初始项。
赋值法是我常用于各种方面,比如理解,
运用一些东西的方法,这里的"值"可以代表很多东西。
/*
slice() 方法可从已有的数组中返回选定的元素。
个人总结语法:
arrayObject.slice(start,end)或arrayObject.slice(start)
arrayObject.slice(start):第start到最后一个的数组中的对象的值
arrayObject.slice(start,end):第start到第end-1个的数组中的对象的值
slice:切
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.slice(1) + "<br />")的结果是John,Thomas
*/
/*
个人使用递归的技巧 START
学习的话就是多做可行的个人技巧总结。
1.在else中写出自己要定义的函数的格式的最终表达式
(else中最终表达式执行的最终结果包括if或包括else if中
写自己要定义的函数的格式的常量可知值表达式就可以)
2.在if,else if中写自己要定义的函数的格式的常量可知值表达式
3.递归就是嵌套循环执行函数,先执行if,else if中的常量可知值表达式,之后只运行else中的式子,
else中的式子运行到
只"运行"if,else if中的常量可知值表达式的情况。
个人使用递归的技巧 END
*/
用递归求斐波那契数或1到100的整数的和,阶乘。
/*
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,
所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。*/
作业:
1、页面上创建10个DIV和一个按钮,当点击按钮时给每个DIV添加文本内容:这是第x个DIV(要求用循环实现,注意闭包问题)
2、创建一个Car类,包含车牌号码和颜色属性,通过闭包实现类似于JAVA中的封装属性的功能
(即只能通过getter和setter方法访问到车牌号码和颜色)
3、面试题的第5题
5. (15分) 请定义一个函数repeat:
function repeat ( func, nums, times ) {
// fill it
}
//函数repeat的调用方法:
var a = repeat( alert, 6,3000 ) ;

个人对闭包的理解 START

老师的理解:
闭包:在一个函数中定义另外一个函数
闭包的特点:内部函数可以访问外部函数中定义的变量
每调用一次外部的函数,就会产生一个独立的闭包(变量环境)
如果内部函数中定义了一个变量跟外部函数中的变量同名,
那么内部函数的变量值会覆盖掉外部函数的变量值
我的理解:
什么是闭包?声明一个变量,声明一个函数,在函数内部访问外部的变量,那么这个函数加这个变量叫做闭包(闭包的声明格式可以解决“内部函数的变量值会覆盖掉外部函数的变量值”等的问题,也就是有时外部函数的for循环的变量值i和外部函数的for循环中的内部函数的变量值i等等会互相独立,解决“外部函数的for循环的变量值i取到最后一个值后,才循环赋值给内部函数的变量值i,i值都变一样”等的问题)。
个人对闭包的理解 END
作业和面试题 START
1、页面上创建10个DIV和一个按钮,当点击按钮时给每个DIV添加文本内容:这是第x个DIV(要求用循环实现,注意闭包问题)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<style>
.create{
width: 50px;
height: 50px;
border: 1px solid darkblue;
}
</style>
<script>
/*有HTML代码的一般都要写window.onload=function(){},
有些不用写,以防万一,js都写在
window.onload=function(){}中。
这里我尝试过,其实不用闭包也可以有效*/
function f(){
var arr=document.getElementsByClassName("create");
for(var i=1;i<=arr.length;i++){
arr[i-1].innerHTML="第"+i+"个div";}
}
window.onload=function(){
document.querySelector("#button1").onclick=function()
{
f();
}
var s="";
for (var i=1;i<=10;i++) {
s=s+"<div class='create'></div>"
}
console.log(s)
var d=document.querySelector("#divAll");
d.innerHTML=s;
//这个id="divAll"的div是不会消失的。
console.log(d)
}
</script>
<body>
<input type="button" value="给每个DIV添加文本内容" id="button1" />
<div id="divAll">
</div>
</body>
</html>



2、创建一个Car类,包含车牌号码和颜色属性,通过闭包实现类似于JAVA中的封装属性的功能
(即只能通过getter和setter方法访问到车牌号码和颜色)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
//实现封装
var Car = function(){
var id = 1;
var color ="blue";
return {
getId: function(){
return id;
},
setId: function(n){
id = n;
}
,
getColor: function(){
return color;
},
setColor: function(n2){
color = n2;
}
};
}
var c2= Car();
c2.setId(2);c2.setColor("red")
console.log("车牌号码:"+c2.getId()+",颜色:"+c2.getColor());
var c1= Car();
console.log("车牌号码:"+c1.getId()+",颜色:"+c1.getColor());
</script>
<body>
</body>
</html>


3、面试题的第5题
5. (15分) 请定义一个函数repeat:
function repeat ( func, nums, times ) {
// fill it
}
//函数repeat的调用方法:
var a = repeat( alert, 6,3000 ) ;
老师的答案:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//func:需要运行的函数
//nums:func函数运行的次数
//times:每次func函数运行的间隔时间(毫秒为单位)
function repeat(func,nums,times){
return function(str){
var iv = setInterval(function(){
func(str);
if(--nums == 0) {
clearInterval(iv);
}
},times);
}
}
var a = repeat(alert,6,2000);
a('你好');
</script>
</head>
<body>
</body>
</html>

我的答案:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
/*面试题个人解析:
1.a("你好");——>a是一个被repeat方法return出来的传一个参数的函数
2.因为return的是函数,所以构成了闭包,闭包的好处就是可以获取外面
函数传来的数值,所以在return的函数中使用repeat(func, nums, times )
中的func, yong'yonnums, times编写程序,
其他就是部分就是学会使用setInterval和clearInterval就可以了*/
function repeat(func, nums, times ) {
// fill it
return function(s){
var i=0;
var c=setInterval(function () {
func(s)
/*更直观的写法1:*/
i++;
console.log(i)
if(i==nums){
clearInterval(c);
}
/*
* 更简洁的写法2:
*
* nums--;
if(nums=0){
clearInterval(c);
}
*/
}, times);
}
}
//函数repeat的调用方法:
var a=repeat(alert,6,3000) ;
//alert(typeof a)
a("你好"); // alert六次"你好",每次间隔3秒
</script>
<body>
</body>
</html>


反例答案:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
function f2(s){
alert(s);
}
function b(func, nums, times ){
var i=0;
var c=setInterval(function (s) {
f2("你好")
i++;
console.log(i)
if(i==nums){
clearInterval(c);
}
}, times);
}
function repeat(func, nums, times ) {
// fill it
// alert(typeof b)
b(func, nums, times );
return f2
}
//函数repeat的调用方法:
var a=repeat(alert,6,3000) ;
//alert(typeof a)
//a("你好"); // alert六次"你好",每次间隔3秒
</script>
<body>
</body>
</html>

作业和面试题 END
课上老师写的代码 START

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//闭包:在一个函数中定义另外一个函数
//闭包的特点:内部函数可以访问外部函数中定义的变量
//每调用一次外部的函数,就会产生一个独立的闭包(变量环境)
var fn1 = function(a){
var b = 'Hello';
return function(){
console.log(b + a);
}
}
fn1('World')();//HelloWorld
fn1('张三')();//Hello张三
//
var test = function(){
var x = 1;
return function(){
x ++;
//alert(x);
}
}
var t1 = test();
t1();//2
t1();//3
var t2 = test();
t2();//2
t1();
//如果内部函数中定义了一个变量跟外部函数中的变量同名,
//那么内部函数的变量值会覆盖掉外部函数的变量值
var fn2 = function(){
console.log(this);//window
var y = 3;
//解决重名变量的冲突
var that = this;
return {
study: function(){
console.log(this);//{}
var y = 4;
console.log(y);
}
}
}
fn2().study();
function helper(n){
return function(){
alert(n);
}
}
function perform(){
var arr = [];
for(var i = 0;i < 5;i ++) {
arr[i] = helper(i);
}
return arr;
}
//perform()[3]();
//实现封装
var person = function(){
var name = 'Tom';
return {
getName: function(){
return name;
},
setName: function(n){
name = n;
}
};
}
var p = person();
p.setName('张三');
console.log(p.getName());
var p1 = person();
console.log(p1.getName());
window.onload = function(){
var btns = document.querySelectorAll('[type="button"]');
for(var i = 0;i < btns.length;i ++) {
btns[i].onclick = helper(i);
}
}
</script>
</head>
<body>
<input type="button" value="测试1" />
<input type="button" value="测试2" />
<input type="button" value="测试3" />
<input type="button" value="测试4" />
<input type="button" value="测试5" />
</body>
</html>



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//求前n个自然数的和
// var sum = 0;
// for(var i = 1;i < n;i ++) {
// sum += i;
// }
function sum(n){
if(n == 1) {//初始条件
return 1;
} else {//递推公式
return sum(n - 1) + n;
}
}
console.log(sum(100));
//求前n个自然数的乘积
function jc(n){
if(n == 1) {
return 1;
} else {
return n * jc(n - 1);
}
}
console.log(jc(5));
function fibonacci(n) {
if(n == 0) {
return 0;
} else if(n == 1) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
console.log(fibonacci(6));
//obj是js对象
//props是数组
//slice方法从指定的数组中截取数组产生一个新的数组
//slice(1)表示从下标1的元素开始,保留后面的所有元素组成一个新的数组
function getVale(obj,props){
if(props.length == 1) {
return obj[props[0]];
} else {
return getVale(obj[props[0]],props.slice(1));
}
}
var o = {
a: {
p: {
name: 'Tom'
}
}
};
var v = getVale(o,['a','p','name']);
console.log(v);//Tom
</script>
</head>
<body>
</body>
</html>


课上老师写的代码 END
课堂跟敲笔记1.html START

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
//递归面试题 START
function getValue(obj,props){
//面试题中要补全的代码:
if(props.length-1==0){return obj[props[0]];}
else{
return getValue(obj[props[0]],props.slice(1))}
/*个人解析:
else中最终表达式执行的最终结果
包括if或包括else if中写自己要定义的函数的格式的常量可知值表达式就可以
该题中的getValue(obj[props[0]],props.slice(1))是最终的表达式。
执行最终的表达式,使用(被)赋值法,obj被赋值为obj[props[0]],
"props"(这里我把双引号中的内容表示为会被赋值的可变部分
双引号在这里仅仅是我的标记,方便读者等等看懂我的意思)被赋值为props.slice(1),
最终 if("props".length-1==0)
中"props".length-1的值会为0,return obj[props[0]];这个初始项。
赋值法是我常用于各种方面,比如理解,
运用一些东西的方法,这里的"值"可以代表很多东西。
*/
}
var o = {
a: {
p: {
name: 'Tom'
}
}
};
var v = getValue(o,['a','p','name']);
console.log(v);//Tom
/*
slice() 方法可从已有的数组中返回选定的元素。
个人总结语法:
arrayObject.slice(start,end)或arrayObject.slice(start)
arrayObject.slice(start):第start到最后一个的数组中的对象的值
arrayObject.slice(start,end):第start到第end-1个的数组中的对象的值
slice:切
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.slice(1) + "<br />")的结果是John,Thomas
*/
//递归面试题 END
/*
个人使用递归的技巧 START
学习的话就是多做可行的个人技巧总结。
1.在else中写出自己要定义的函数的格式的最终表达式
(else中最终表达式执行的最终结果包括if或包括else if中
写自己要定义的函数的格式的常量可知值表达式就可以)
2.在if,else if中写自己要定义的函数的格式的常量可知值表达式
3.递归就是嵌套循环执行函数,先执行if,else if中的常量可知值表达式,之后只运行else中的式子,
else中的式子运行到
只"运行"if,else if中的常量可知值表达式的情况。
个人使用递归的技巧 END
*/
//用递归求斐波那契数或1到100的整数的和,阶乘。 START
// 斐波那契数:
//0,1,1,2,3,5
/*这里的n代表项数,如果f(0)=0,那么n代表的下标,if条件就要变成if(n==0){return 0;}
if(n==1){return 1;}*/
function f(n){
if(n==1){return 0;}
if(n==2){return 1;}
else{
return f(n-1)+f(n-2);
}
}
console.log(f(1))
//和:
function sum(n){
if(n==1){return 1;}
else{
return sum(n-1)+n;
}
}
console.log(sum(5))
// 阶乘:
function jc(n){
if(n==1){return 1;}
else{
return jc(n-1)*n;
}
}
console.log(jc(5))
//用递归求斐波那契数或1到100的整数的和,阶乘。END
//闭包 START
/*
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,
所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。*/
var a=function(){
var x=1;
return function(){
x++;
alert(x)
}
}
var a1=a();
a1();
a1()
var a2=a();
a2()
//闭包 END
</script>
<body>
</body>
</html>




