JS遞歸,斐波那契數(shù),slice,閉包,面試題,setInterval,clearInterval【詩(shī)書(shū)畫(huà)唱】
概括:
個(gè)人對(duì)閉包的理解
面試題的第5題
老師的答案
我的答案
作業(yè)和面試題
課上老師寫(xiě)的代碼
課堂跟敲筆記1.html
面試題個(gè)人解析
setInterval
clearInterval
//閉包:在一個(gè)函數(shù)中定義另外一個(gè)函數(shù)
//閉包的特點(diǎn):內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)中定義的變量
//每調(diào)用一次外部的函數(shù),就會(huì)產(chǎn)生一個(gè)獨(dú)立的閉包(變量環(huán)境)
//如果內(nèi)部函數(shù)中定義了一個(gè)變量跟外部函數(shù)中的變量同名,
//那么內(nèi)部函數(shù)的變量值會(huì)覆蓋掉外部函數(shù)的變量值
//解決重名變量的沖突
//實(shí)現(xiàn)封裝
//求前n個(gè)自然數(shù)的和
//初始條件
//遞推公式
?//求前n個(gè)自然數(shù)的乘積
? ? //obj是js對(duì)象
? ? ? ? ? ? //props是數(shù)組
? ? ? ? ? ? //slice方法從指定的數(shù)組中截取數(shù)組產(chǎn)生一個(gè)新的數(shù)組
? ? ? ? ? ? //slice(1)表示從下標(biāo)1的元素開(kāi)始,保留后面的所有元素組成一個(gè)新的數(shù)組
遞歸面試題
面試題中要補(bǔ)全的代碼
個(gè)人解析:
?
?else中最終表達(dá)式執(zhí)行的最終結(jié)果
?包括if或包括else if中寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式就可以?
該題中的getValue(obj[props[0]],props.slice(1))是最終的表達(dá)式。
執(zhí)行最終的表達(dá)式,使用(被)賦值法,obj被賦值為obj[props[0]],
"props"(這里我把雙引號(hào)中的內(nèi)容表示為會(huì)被賦值的可變部分
雙引號(hào)在這里僅僅是我的標(biāo)記,方便讀者等等看懂我的意思)被賦值為props.slice(1),
最終 if("props".length-1==0)
中"props".length-1的值會(huì)為0,return obj[props[0]];這個(gè)初始項(xiàng)。
賦值法是我常用于各種方面,比如理解,
運(yùn)用一些東西的方法,這里的"值"可以代表很多東西。
/*
?slice() 方法可從已有的數(shù)組中返回選定的元素。
?個(gè)人總結(jié)語(yǔ)法:
arrayObject.slice(start,end)或arrayObject.slice(start)
arrayObject.slice(start):第start到最后一個(gè)的數(shù)組中的對(duì)象的值
arrayObject.slice(start,end):第start到第end-1個(gè)的數(shù)組中的對(duì)象的值
slice:切
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.slice(1) + "<br />")的結(jié)果是John,Thomas
*/
/*
個(gè)人使用遞歸的技巧?START
學(xué)習(xí)的話就是多做可行的個(gè)人技巧總結(jié)。
1.在else中寫(xiě)出自己要定義的函數(shù)的格式的最終表達(dá)式
(else中最終表達(dá)式執(zhí)行的最終結(jié)果包括if或包括else if中
寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式就可以)
2.在if,else if中寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式
3.遞歸就是嵌套循環(huán)執(zhí)行函數(shù),先執(zhí)行if,else if中的常量可知值表達(dá)式,之后只運(yùn)行else中的式子,
else中的式子運(yùn)行到
只"運(yùn)行"if,else if中的常量可知值表達(dá)式的情況。
個(gè)人使用遞歸的技巧 END
*/
用遞歸求斐波那契數(shù)或1到100的整數(shù)的和,階乘。
/*
?閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。例如在javascript中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,
?所以閉包可以理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)“。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的橋梁。*/
作業(yè):
1、頁(yè)面上創(chuàng)建10個(gè)DIV和一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕時(shí)給每個(gè)DIV添加文本內(nèi)容:這是第x個(gè)DIV(要求用循環(huán)實(shí)現(xiàn),注意閉包問(wèn)題)
2、創(chuàng)建一個(gè)Car類,包含車牌號(hào)碼和顏色屬性,通過(guò)閉包實(shí)現(xiàn)類似于JAVA中的封裝屬性的功能
(即只能通過(guò)getter和setter方法訪問(wèn)到車牌號(hào)碼和顏色)
3、面試題的第5題
5. (15分) 請(qǐng)定義一個(gè)函數(shù)repeat:
function repeat ( func, nums, times ) {
// fill it
}
//函數(shù)repeat的調(diào)用方法:?
var a = repeat( alert, 6,3000 ) ;

個(gè)人對(duì)閉包的理解 START

老師的理解:
閉包:在一個(gè)函數(shù)中定義另外一個(gè)函數(shù)
閉包的特點(diǎn):內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)中定義的變量
每調(diào)用一次外部的函數(shù),就會(huì)產(chǎn)生一個(gè)獨(dú)立的閉包(變量環(huán)境)
如果內(nèi)部函數(shù)中定義了一個(gè)變量跟外部函數(shù)中的變量同名,
那么內(nèi)部函數(shù)的變量值會(huì)覆蓋掉外部函數(shù)的變量值
我的理解:
什么是閉包?聲明一個(gè)變量,聲明一個(gè)函數(shù),在函數(shù)內(nèi)部訪問(wèn)外部的變量,那么這個(gè)函數(shù)加這個(gè)變量叫做閉包(閉包的聲明格式可以解決“內(nèi)部函數(shù)的變量值會(huì)覆蓋掉外部函數(shù)的變量值”等的問(wèn)題,也就是有時(shí)外部函數(shù)的for循環(huán)的變量值i和外部函數(shù)的for循環(huán)中的內(nèi)部函數(shù)的變量值i等等會(huì)互相獨(dú)立,解決“外部函數(shù)的for循環(huán)的變量值i取到最后一個(gè)值后,才循環(huán)賦值給內(nèi)部函數(shù)的變量值i,i值都變一樣”等的問(wèn)題)。
個(gè)人對(duì)閉包的理解 END
作業(yè)和面試題 START
1、頁(yè)面上創(chuàng)建10個(gè)DIV和一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕時(shí)給每個(gè)DIV添加文本內(nèi)容:這是第x個(gè)DIV(要求用循環(huán)實(shí)現(xiàn),注意閉包問(wèn)題)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<style>
.create{
width: 50px;
height: 50px;
border: 1px solid darkblue;
}
</style>
<script>
/*有HTML代碼的一般都要寫(xiě)window.onload=function(){},
有些不用寫(xiě),以防萬(wàn)一,js都寫(xiě)在
window.onload=function(){}中。
這里我嘗試過(guò),其實(shí)不用閉包也可以有效*/
function f(){
var arr=document.getElementsByClassName("create");
for(var i=1;i<=arr.length;i++){
arr[i-1].innerHTML="第"+i+"個(gè)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;
//這個(gè)id="divAll"的div是不會(huì)消失的。
console.log(d)
}
</script>
<body>
<input type="button"? value="給每個(gè)DIV添加文本內(nèi)容" id="button1" />
<div id="divAll">
</div>
</body>
</html>



2、創(chuàng)建一個(gè)Car類,包含車牌號(hào)碼和顏色屬性,通過(guò)閉包實(shí)現(xiàn)類似于JAVA中的封裝屬性的功能
(即只能通過(guò)getter和setter方法訪問(wèn)到車牌號(hào)碼和顏色)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
//實(shí)現(xiàn)封裝
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("車牌號(hào)碼:"+c2.getId()+",顏色:"+c2.getColor());
var c1= Car();
console.log("車牌號(hào)碼:"+c1.getId()+",顏色:"+c1.getColor());
</script>
<body>
</body>
</html>


3、面試題的第5題
5. (15分) 請(qǐng)定義一個(gè)函數(shù)repeat:
function repeat ( func, nums, times ) {
// fill it
}
//函數(shù)repeat的調(diào)用方法:?
var a = repeat( alert, 6,3000 ) ;
老師的答案:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//func:需要運(yùn)行的函數(shù)
//nums:func函數(shù)運(yùn)行的次數(shù)
//times:每次func函數(shù)運(yùn)行的間隔時(shí)間(毫秒為單位)
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>
/*面試題個(gè)人解析:
?1.a("你好");——>a是一個(gè)被repeat方法return出來(lái)的傳一個(gè)參數(shù)的函數(shù)
?2.因?yàn)閞eturn的是函數(shù),所以構(gòu)成了閉包,閉包的好處就是可以獲取外面
?函數(shù)傳來(lái)的數(shù)值,所以在return的函數(shù)中使用repeat(func, nums, times )
?中的func, yong'yonnums, times編寫(xiě)程序,
?其他就是部分就是學(xué)會(huì)使用setInterval和clearInterval就可以了*/
function repeat(func, nums, times ) {
// fill it
return function(s){
var i=0;
var c=setInterval(function () {
func(s)
/*更直觀的寫(xiě)法1:*/
i++;
console.log(i)
if(i==nums){
clearInterval(c);
}
/*
?* 更簡(jiǎn)潔的寫(xiě)法2:
?*?
?* nums--;
if(nums=0){
clearInterval(c);
}
*/
}, times);
}
}
//函數(shù)repeat的調(diào)用方法:?
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
}
//函數(shù)repeat的調(diào)用方法:?
var a=repeat(alert,6,3000) ;
//alert(typeof a)
//a("你好"); // alert六次"你好",每次間隔3秒
</script>
<body>
</body>
</html>

作業(yè)和面試題?END
課上老師寫(xiě)的代碼 START

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//閉包:在一個(gè)函數(shù)中定義另外一個(gè)函數(shù)
//閉包的特點(diǎn):內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)中定義的變量
//每調(diào)用一次外部的函數(shù),就會(huì)產(chǎn)生一個(gè)獨(dú)立的閉包(變量環(huán)境)
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();
//如果內(nèi)部函數(shù)中定義了一個(gè)變量跟外部函數(shù)中的變量同名,
//那么內(nèi)部函數(shù)的變量值會(huì)覆蓋掉外部函數(shù)的變量值
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]();
//實(shí)現(xiàn)封裝
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="測(cè)試1" />
<input type="button" value="測(cè)試2" />
<input type="button" value="測(cè)試3" />
<input type="button" value="測(cè)試4" />
<input type="button" value="測(cè)試5" />
</body>
</html>



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
//求前n個(gè)自然數(shù)的和
// 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個(gè)自然數(shù)的乘積
? ? ? ? ? ? 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對(duì)象
? ? ? ? ? ? //props是數(shù)組
? ? ? ? ? ? //slice方法從指定的數(shù)組中截取數(shù)組產(chǎn)生一個(gè)新的數(shù)組
? ? ? ? ? ? //slice(1)表示從下標(biāo)1的元素開(kāi)始,保留后面的所有元素組成一個(gè)新的數(shù)組
? ? ? ? ? ? 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>


課上老師寫(xiě)的代碼 END
課堂跟敲筆記1.html START

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script>
//遞歸面試題 START
? ?function getValue(obj,props){
? ? //面試題中要補(bǔ)全的代碼:
? if(props.length-1==0){return obj[props[0]];}
? else{?
?
? return getValue(obj[props[0]],props.slice(1))}
??
/*個(gè)人解析:
?
?else中最終表達(dá)式執(zhí)行的最終結(jié)果
?包括if或包括else if中寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式就可以?
該題中的getValue(obj[props[0]],props.slice(1))是最終的表達(dá)式。
執(zhí)行最終的表達(dá)式,使用(被)賦值法,obj被賦值為obj[props[0]],
"props"(這里我把雙引號(hào)中的內(nèi)容表示為會(huì)被賦值的可變部分
雙引號(hào)在這里僅僅是我的標(biāo)記,方便讀者等等看懂我的意思)被賦值為props.slice(1),
最終 if("props".length-1==0)
中"props".length-1的值會(huì)為0,return obj[props[0]];這個(gè)初始項(xiàng)。
賦值法是我常用于各種方面,比如理解,
運(yùn)用一些東西的方法,這里的"值"可以代表很多東西。
*/
??
??
}
? ? ? ? ? ? var o = {
? ? ? ? ? ? a: {
? ? ? ? ? ? p: {
? ? ? ? ? ? name: 'Tom'
? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? };
var v = getValue(o,['a','p','name']);
console.log(v);//Tom
/*
?slice() 方法可從已有的數(shù)組中返回選定的元素。
?個(gè)人總結(jié)語(yǔ)法:
arrayObject.slice(start,end)或arrayObject.slice(start)
arrayObject.slice(start):第start到最后一個(gè)的數(shù)組中的對(duì)象的值
arrayObject.slice(start,end):第start到第end-1個(gè)的數(shù)組中的對(duì)象的值
slice:切
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.slice(1) + "<br />")的結(jié)果是John,Thomas
*/
//遞歸面試題 END
/*
個(gè)人使用遞歸的技巧 START
學(xué)習(xí)的話就是多做可行的個(gè)人技巧總結(jié)。
1.在else中寫(xiě)出自己要定義的函數(shù)的格式的最終表達(dá)式
(else中最終表達(dá)式執(zhí)行的最終結(jié)果包括if或包括else if中
寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式就可以)
2.在if,else if中寫(xiě)自己要定義的函數(shù)的格式的常量可知值表達(dá)式
3.遞歸就是嵌套循環(huán)執(zhí)行函數(shù),先執(zhí)行if,else if中的常量可知值表達(dá)式,之后只運(yùn)行else中的式子,
else中的式子運(yùn)行到
只"運(yùn)行"if,else if中的常量可知值表達(dá)式的情況。
個(gè)人使用遞歸的技巧 END
*/
//用遞歸求斐波那契數(shù)或1到100的整數(shù)的和,階乘。 START
// 斐波那契數(shù):
//0,1,1,2,3,5
/*這里的n代表項(xiàng)數(shù),如果f(0)=0,那么n代表的下標(biāo),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))
//用遞歸求斐波那契數(shù)或1到100的整數(shù)的和,階乘。END
//閉包 START
/*
?閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。例如在javascript中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,
?所以閉包可以理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)“。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的橋梁。*/
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>




