## 復(fù)習(xí): 第三天課程
? ? 1一膨、數(shù)組創(chuàng)建方法 2種方法
答:1谨湘、var? arr = new Array(); 使用 new? Array 方法
答:2樱报、var arr = [] 字面量方式
2息罗、var arr = [1,2,3,4];說(shuō)出什么是數(shù)組元素芋齿,什么是下標(biāo)
答 :[1,2,3,4] 是數(shù)組元素 啸如,下標(biāo)是序號(hào)0侍匙,1,2....開(kāi)始的
3叮雳、如何獲取數(shù)組的長(zhǎng)度
答:length? 就是數(shù)組的個(gè)數(shù)
4想暗、如何遍歷數(shù)組
答:for 從頭到尾選擇的for里面有個(gè)i 當(dāng)索引號(hào)看
5、增加數(shù)組元素是如何實(shí)現(xiàn)的
答:數(shù)組名[索引號(hào)] = '值'
arr[0] = 123,
6帘不、為什么需要函數(shù)
答:代碼多次復(fù)用说莫,多次調(diào)用
7、函數(shù)是怎么聲明的和調(diào)用的
答:function 聲明 使用 函數(shù)名加小括號(hào)? 調(diào)用? function fn(){} fn();
8寞焙、function f(x,y){xxxx} f(1,3) 請(qǐng)說(shuō)出那個(gè)是實(shí)參那個(gè)是形參
答:f(1,3)實(shí)參储狭, f(x,y)是形參,x,y相當(dāng)于變量
9捣郊、函數(shù)的返回值辽狈,是返回給誰(shuí)的?
答:return? 誰(shuí)調(diào)用return 返回給誰(shuí)
## 今天全天都講函數(shù):就是這么多 對(duì)我來(lái)說(shuō)都很重要
### 每個(gè)練習(xí)題我會(huì)詳細(xì)講到每個(gè)步驟
? ? 1呛牲、函數(shù)練習(xí)
? ? 2稻艰、函數(shù)參數(shù)和返回值注意事項(xiàng)
? ? 3、arguments 的使用
? ? 4侈净、定義函數(shù)的兩種方式
? ? 5尊勿、自執(zhí)行函數(shù)
? ? 6僧凤、函數(shù)也是一種數(shù)據(jù)類(lèi)型 function
? ? 7、函數(shù)可以作為參數(shù)
? ? 8元扔、函數(shù)可以作為返回值
? ? 9躯保、作用域
? ? 10、作用域鏈
? ? 11澎语、預(yù)解析
## 1途事、練習(xí)
? ? 1、函數(shù) 封裝 翻轉(zhuǎn)數(shù)組
? ? 思路:
1擅羞、翻轉(zhuǎn)數(shù)組尸变,返回一個(gè)新數(shù)組
2、把內(nèi)容封裝到函數(shù)里面去reverse 反轉(zhuǎn) reverse記住后面有個(gè)方法
//這里的arr 是形參
function reverse(arr){
// 新數(shù)組接收方
var newArr = [];
// 遍歷循環(huán)
for(var i=0; i<arr.length;i++){
// 接收方 舊數(shù)組長(zhǎng)度 - i-1减俏,每次循環(huán)都給一次
newArr[i] = arr[arr.length-i-1];
}
// 誰(shuí)調(diào)用給誰(shuí)召烂,不然就會(huì)undefined
return newArr;
}
//把數(shù)組要傳輸?shù)胶瘮?shù)里面通過(guò) 形參? 參數(shù) 傳遞
var arr = [1,2,3,4,5]; //這個(gè)arr 是數(shù)組名
reverse(arr); //函數(shù)調(diào)用是 實(shí)參
// 打印數(shù)組 翻轉(zhuǎn)成功
console.log(reverse(arr));
// 第二種數(shù)組傳參方法?
console.log(reverse(['red','pink','green']));
? ? 2、函數(shù) 封裝冒泡
? ? ? ? //冒泡 需要兩個(gè)for 循環(huán) 外層 for 需要趟數(shù) 長(zhǎng)度減去 1
// 里層的for 循環(huán) 管交換次數(shù)? 長(zhǎng)度 減去 i 減去 1
// 交換2個(gè)值?
// 后面會(huì)學(xué)到sort 算法
function sort(arr){
? ? for(var i=0; i<arr.length-1;i++){
? ? for(var j=0; j<arr.length-i-1;j++){
? ? // 比較 arr[j] 是0 開(kāi)始比較
? ? if(arr[j] < arr[j+1]){
? ? var temp = arr[j];? //保存第一個(gè)
? ? arr[j] = arr[j+1]; //第二個(gè)給第一個(gè)
? ? arr[j+1] = temp;
? ? }
? ? }
? ? }
? ? // return 出去
? ? return arr;
}
var arr = [1,3,5,7,8,10];
console.log(sort(arr))
3娃承、函數(shù) 封裝閏年
? ? //函數(shù) 需要接受的年份,能被4這整除 并且不能被100整除奏夫,或者能被400 整除
function isRun(year){
// 這里的flag 一個(gè)變量來(lái)控制 用來(lái)存儲(chǔ) 是不是閏年的
var flag = false; //剛開(kāi)始默認(rèn)的就是false? 默認(rèn)的是 平年 flag 是開(kāi)關(guān)
// 你這里的條件是不是閏年啊历筝?
if(year % 4 === 0 && year % 100 !==0 || year % 400 ===0 ){
//是true 就會(huì)覆蓋掉了酗昼,flag 里面存儲(chǔ)的要么是true要不就是false
flag = true;
}
// 然后return 出去
return flag
}
console.log(isRun(2019));
4、計(jì)算2019年2月15日是一年中的第幾天
這個(gè)案例的核心就函數(shù)可以調(diào)用函數(shù)
? ? //獲得天數(shù)的函數(shù)
function getDays(year,month,day){
// days 存儲(chǔ)的總天數(shù),
// day先存儲(chǔ)當(dāng)月的天數(shù)
// var days = 0;
//? days += day;
var days = day
// 月份有很多我們需要for 循環(huán),詳細(xì)介紹當(dāng)月天數(shù)只能從 1月份開(kāi)始梳猪,小于你輸入的天數(shù)
for(var i=1; i<month; i++){
switch (i) {
case 1 :
case 3 :
case 5 :
case 7 :
case 8 :
case 10 :
case 12 :
days += 31;
break;
case 4:
case 6:
case 9:
case 11:
days +=30;
break;
case 2:
// 如果是閏年 +=29年
// 否則是平年 +=28天
// 在函數(shù)里面右調(diào)用了一個(gè)函數(shù)
if(getRun(year)){
days+=29;
}else {
days+=28;
}
break;
}
}
// 先return days
return days
}
console.log(getDays(2018,2,15));
// 這里我們拿到之前寫(xiě)的函數(shù) 進(jìn)行平年潤(rùn)年的判斷
function getRun(year){
var flag = false;
if(year % 4 === 0 && year % 100 !==0 ||year % 400 === 0){
flag = true
}
return flag;
}
思路:
1麻削、輸入某年某月某日判斷這一天是這一年的第幾天
2、比如要輸入年份春弥,因?yàn)橛虚c年和平年碟婆,也要區(qū)分開(kāi)
3、月份不一樣 有的是30天 有的是31天
4惕稻、先算當(dāng)月的天數(shù)
5竖共、前面幾個(gè)月的總天數(shù) + 不斷的相加 for 循環(huán)
## 斐波那契額數(shù)列:1,1俺祠,2公给,3,5蜘渣,8淌铐,13,21
會(huì)發(fā)現(xiàn)處理第一個(gè)和第二個(gè)之外 后面第三個(gè)都是前一個(gè)數(shù)字相加
? ? //思路就是
? ? var n1 = 1;
? ? var n2 = 1;
? ? var n3 = 0;
? ? // n3 = n1 + n2 等出來(lái)的
? ? for(var i=3; i<= 9; i++){
? ? // 第一輪求出n3
? ? n3 = n1 + n2;
? ? // n1等于1
? ? n1 = n2;
? ? //? n2 是 2?
? ? n2 = n3
? ? // 正好是下一輪的 n1+n2
? ? }
? ? 看圖來(lái)操作:n1 正好是1 n2 也是1 n3是n1+n2的結(jié)果
![](https://user-gold-cdn.xitu.io/2019/2/17/168fa2a11b557f6c?w=932&h=584&f=png&s=55244)
? ? 封裝斐波那契數(shù)列 :
? ? function getFei(num){
var n1 = 1;
var n2 = 1;
var n3 = 0;
for(var i=3; i<=num;i++){
n3 = n1 + n2;
n1 = n2;
n2 = n3;
}
return n3;
}
console.log(getFei(9));
詳細(xì)解釋?zhuān)?/p>
前面兩項(xiàng)相加得到第三項(xiàng)
所有我們需要 三個(gè)變量 n1 + n2 = n3;
var n1 = 1;
var n2 = 1;
var n3 = 0;
問(wèn)的是第 n 個(gè) 88 個(gè)蔫缸? 循環(huán) i就是幾個(gè) 循環(huán)幾次
for(var i= 3; i<=9; i++){
n3 是 第n個(gè)數(shù)的數(shù)字 多少
m3 = n1 + n2;
n1 = n2 ;
n2 = n3;
}
console.log(9)
## 函數(shù)參數(shù)和返回值注意事項(xiàng)
? ? function fn(){
return 555;
}
// 函數(shù)調(diào)用返回函數(shù)值 555? 函數(shù)名+ 括號(hào) 調(diào)用函數(shù) 執(zhí)行函數(shù)
console.log(fn());
// 打印出函數(shù)的 本身 函數(shù)名 輸出的函數(shù)本身
console.log(fn);
這里為了arguments 參數(shù) 鋪墊? 請(qǐng)看好
? ? function funn(){
}
// 如果函數(shù)沒(méi)有返回值 返回undefined? 沒(méi)有return
console.log(funn());
function getSum(x,y,z){
return x + y + z;
}
console.log(getSum(1,2,3)); //6
console.log(getSum(1,2,3,6));//6
console.log(getSum(1,2));//NaN? 1+ 2 + undefined? = NaN
// undefined + 任何數(shù)值 都是NaN 除了字符串
// 疑問(wèn)腿准? 用戶(hù)要是想輸入多少是多少怎么辦呢? 使用arguments 的使用
##? 疑問(wèn)? 用戶(hù)要是想輸入多少是多少怎么辦呢吐葱? 使用arguments 的使用
arguments 的使用
js中arguments 對(duì)象是比較特別的一個(gè)對(duì)象街望,實(shí)際上是當(dāng)前函數(shù)的內(nèi)置屬性,也就是伙食所有函數(shù)都內(nèi)置了一個(gè)
arguments對(duì)象 arguments 對(duì)象中存儲(chǔ)了傳遞的所有的實(shí)參弟跑,arguments是一個(gè)偽數(shù)組
? ### arguments 對(duì)象中存儲(chǔ)了傳遞的所有的實(shí)參
? function getSum() {
// 可以接受 傳遞過(guò)來(lái)的所有的 實(shí)參
// arguments 是一個(gè)偽數(shù)組
console.log(arguments);
// 存儲(chǔ)形式 偽數(shù)組
// 遍歷數(shù)組 可以把值取出來(lái)
}
getSum(1,2,3,1,2,3);
? ? 案例: 可以求任意數(shù)值的和
? ? ? ? ? ? function getSum(){
? ? ? ? var sum = 0;
? ? ? ? for(var i=0; i<arguments.length;i++){
? ? ? ? sum += arguments[i];
? ? ? ? }
? ? ? ? return sum;
? ? ? ? }
? ? ? ? console.log(getSum(1,2,3));
? ? 案例:求任意數(shù)的最大值
? ? ? ? function gemMax(){
var max = arguments[0];
console.log(max);//1
for(var i=0;i<arguments.length; i++){
if(max < arguments[i]){
max = arguments[i];
}
}
return max;
}
console.log(gemMax(1,2,3,4,5,));
## 函數(shù)的定義撒三種方式
? ? 定義函數(shù)的3中方式
1灾前、聲明函數(shù) 命名函數(shù)
function fn(){
}
fn();
答:實(shí)際工作使用多
2、函數(shù)表達(dá)式 匿名函數(shù)
var fun = function(){};
? ? 答:Dom操作的時(shí)候使用較多
? ? 3孟辑、自執(zhí)行 函數(shù)
答:匿名函數(shù)除了 作為參數(shù)傳遞外哎甲,也可以作為啟動(dòng)函數(shù),定以后立即執(zhí)行,為了防止變量污染
匿名 函數(shù)自執(zhí)行函數(shù)饲嗽,最大的好處炭玫,就是防止命名沖突 后面會(huì)講
函數(shù)不調(diào)用不執(zhí)行,但是自執(zhí)行函數(shù)自己調(diào)用自己
(function (){
}) ();
## 函數(shù)作為參數(shù)使用
解答:函數(shù)可以接受任何類(lèi)型的數(shù)據(jù)作為參數(shù)貌虾,數(shù)值吞加,字符甚至是函數(shù)類(lèi)型
var fn = function(){
console.log('這里是一個(gè)函數(shù)');
}
// 聲明
function fun(x){
console.log(x);
x();
}
// 調(diào)用
fun(fn);
## 函數(shù) 可以作為返回值
? ? /*
function fn(){} //聲明函數(shù)
console.log(fn); //輸出整個(gè)函數(shù) 代碼
console.log(fn()) //fn()調(diào)用函數(shù) 執(zhí)行函數(shù)
function fn(){
retrun? 666;
}
console.log(fn(666)); //返回值 666
*/
function fn(){
//返回的是一個(gè)函數(shù)
return function (){
console.log('返回這里的函數(shù)');
}
}
// console.log(fn());? function (){console.log('返回這里的函數(shù)')};
var ff = fn(); //function (){console.log('返回這里的函數(shù)')};
ff();
//console.log(ff); //function (){console.log('返回這里的函數(shù)')};
## 作用域
答: 作用域: 變量可以起作用的范圍
? ? 全局變量和局部變量
? ? 全局作用域
? ? 供所有代碼執(zhí)行的環(huán)境整個(gè)Script 標(biāo)簽內(nèi)部 或者一個(gè)獨(dú)立的js 文件中
? ? 局部作用域
? ? 在調(diào)用函數(shù)的時(shí)候 會(huì)形參一個(gè)執(zhí)行函數(shù)內(nèi)代碼的新環(huán)境
? ? 全局變量
? ? 在全局作用域下聲明的變量叫做全局變量
? ? 全局變量在代碼任何位置都可以使用
? ? 局部變量
? ? 在局部作用域下聲明的變量叫做局部變量
? ? 局部變量只能在該函數(shù)內(nèi)部使用
? ? //全局作用域?
? ? //num 就是一個(gè)全局 變量
? ? var num = 10;
? ? console.log(num);
? ? //在function 里面寫(xiě)的是 局部作用域
? ? function fun(){
? ? //str 在 局部?jī)?nèi)寫(xiě)的是局部變量
? ? var str = '';
? ? //全局變量可以全局使用
? ? console.log(num);
? ? }
? ? fun()//進(jìn)行調(diào)用
? ? console.log(str);
? ? 注意 : 函數(shù)的形參實(shí)際上就是局部變量
局部變量當(dāng)其所在的代碼塊被執(zhí)行時(shí)候,會(huì)被初始化酝惧,當(dāng)代碼塊運(yùn)行結(jié)束后榴鼎,就被銷(xiāo)毀了伯诬,節(jié)省內(nèi)存空間
全局變量因?yàn)槿魏我粋€(gè)地方都可以使用晚唇,只有在瀏覽器關(guān)閉才會(huì)銷(xiāo)毀,比較占內(nèi)存
## 作用域鏈:
? ? ? ? ? ? 只要是代碼盗似,就至少有一個(gè)作用域
寫(xiě)在函數(shù)外部的就全局作用域
寫(xiě)在函數(shù)內(nèi)部的就是局部作用域
如果函數(shù)中還有函數(shù)哩陕,那么在這個(gè)作用域中就又誕生一個(gè)作用域
根據(jù)在內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)變量的這種機(jī)制,用鏈?zhǔn)讲檎覜Q定哪些數(shù)據(jù)能被內(nèi)部函數(shù)訪問(wèn)赫舒,就稱(chēng)作作用域鏈
練習(xí)題:
function f1(){
function f2(){
}
}
var num = 123;
function f3(){
function f4(){
}
}
//? 解答: f1 和 num? f3 是屬于 零級(jí)鏈 就是最牛的那個(gè) 相當(dāng)于盤(pán)古
案例:
? ? function f1(){
var num = 123;
function f2(){
console.log(num);
}
f2();
}
var num = 456;
f1();
// 案例
function f1(){
// var num = 123;
function f2(){
console.log(num);
}
f2();
}
// var num = 456;
var num;
f1();
// 解答: 零級(jí)鏈 f1 和num 是零級(jí)鏈
// f1里面的 num? 和 f2 是一級(jí)鏈
// console.log(num) 是 二級(jí)鏈
// 假設(shè)如果 我們一級(jí)鏈 里面沒(méi)有找到 123
就會(huì)繼續(xù)冒泡向上查找 找到? 456 如果還沒(méi)有就會(huì)undefined
練習(xí)題: 答案 留在 評(píng)論 寫(xiě):作用域練習(xí)題1與2的答案即可悍及。
var? a = 1;
function f1(){
var a = 2;
var b = '2b';
function f2(){
var a = 3;
function f3(){
var a = 4;
console.log(a); //a 的值 4
console.log(b);? //b 的值 '2b';
}
f3();
}
f2()
}
f1();
? ? 練習(xí)題2:
? ? var? a = 1;
function f1(){
var a = 2;
var b = '2b';
function f2(){
var a = 3;
function f3(){
var a = 4;
console.log(a); //a 的值 4
console.log(b);? //b 的值 '2b';
}
}
}
## 預(yù)解析 重要?
? ? /*
// console.log(num);? //打印出什么? num is not defined? 未定義
var num ;
console.log(num); // undefined? 聲明變量未給值
var num = 10;
console.log(num)? //輸出 10
console.log(num);? // 請(qǐng)問(wèn) 預(yù)解析? 這里輸出是undefined
var num = 10;
fun(); //函數(shù)調(diào)用把下面的注釋了,在上面輸出你會(huì)發(fā)現(xiàn)什么 下面也會(huì)打印出來(lái)
function fun(){
console.log('人啊不能偷懶');
}
//fun(); 函數(shù)調(diào)用?
*/
? ? ? ? js 解析器 就是js 引擎
解答:javascript代碼是由瀏覽器中的js 解析器來(lái)執(zhí)行的接癌,js解析器在運(yùn)行js代碼的時(shí)候心赶,分為兩步預(yù)解析和代碼執(zhí)行
為什么學(xué)習(xí)預(yù)解析?
答:學(xué)習(xí)了預(yù)解析能夠讓我們知道為什么在變量聲明之前訪問(wèn)變量缺猛,值是undefined 為什么 在函數(shù)聲明之前就可以調(diào)用函數(shù)
預(yù)解析過(guò)程:
1缨叫、js解析器會(huì)在全局環(huán)境下查找 var function 關(guān)鍵字,變量只聲明不賦值荔燎,函數(shù)聲明不調(diào)用
2耻姥、預(yù)解析只發(fā)生在當(dāng)前作用域下
預(yù)解析也叫做變量,函數(shù)提升
1有咨、變量提升:定義變量的時(shí)候琐簇,變量的聲明會(huì)被提升到當(dāng)前作用域的最上面啊,變量的賦值不會(huì)提升
2座享、函數(shù)提升:js解析器首先會(huì)把當(dāng)前作用的函數(shù)聲明提前到整個(gè)作用域的最前面
優(yōu)先等級(jí):變量名和函數(shù)名相同婉商,有限執(zhí)行函數(shù)? 重點(diǎn)
執(zhí)行過(guò)程:
變量賦值似忧,函數(shù)調(diào)用,表達(dá)式運(yùn)算等等
上面題講解:
? ? console.log(num);
? ? var num = 10;
? 解答: 這里為什么 會(huì)打印出undefined 是因?yàn)?變量提升据某,變成了
? var num;
? console.log(num);
? num = 10; 變量的賦值不會(huì)提升也就說(shuō)沒(méi)有把10賦值給num 聲明變量未給值
上面題講解:
? ? fn();
function fn(){
}
// 為什么 這么寫(xiě)沒(méi)問(wèn)題呢橡娄?
// 因?yàn)閖s 預(yù)解析 會(huì)把我們函數(shù) 提升回來(lái) 請(qǐng)看
function fn(){
// 預(yù)解析的功勞 提升回來(lái)了,但是變量的聲明會(huì)被提前癣籽,但是值并不會(huì)
// 所以這里就變成了聲明變量未給值 so undefined 了 函數(shù)是整體的函數(shù)聲明所以提前了
}
fn();
預(yù)解析練習(xí)題:
? 到時(shí)候把答案 寫(xiě)在 留言區(qū)吧
? ? ? ? 格式:? 預(yù)解析練習(xí)題- 1- 答案
? ? 題目1挽唉、
? ? ? ? ? ? alert(a);
? ? alert(fn);
? ? var a? =1;
? ? function fn(){
? ? return false;
? ? }
? ? 題目2、
? ? ? ? ? ? alert(a);
var a = 1;
alert(a);
function a(){
return false;
}
? ? 解答提示:變量名 和函數(shù)名 相同的情況
? ? 題目3筷狼、
? ? ? ? var num = 10;
fun();
function fun(){
console.log(num);
var num = 20;
}
題目4瓶籽、
? ? var num? = 10;
fn();
function fn(){
console.log(num);
var num = 20;
console.log(num);
}
? ? 題目5、
? ? ? ? var a = 10;
? ? f1();
? ? function f1(){
? ? var b = 20;
? ? console.log(a);
? ? console.log(b);
? ? var a = '123';
? ? }
## 全局變量的特殊形式
? ? var num =10; //全局變量
function fun (){
var n = 20; //局部變量
str = 'jack'; //str 放在局部作用域中,全局變量的特殊形式埂材,在局部作用域內(nèi)聲明塑顺,但是沒(méi)寫(xiě)var 當(dāng)全局變量看
}
fun();? //記著調(diào)用
console.log(str);
題目6、
? ? f1()
console.log(c)
console.log(b)
console.log(a)
function f1(){
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
## 問(wèn)答:
? ? 問(wèn)答:
1俏险、函數(shù)形參和實(shí)參個(gè)數(shù) 可以不匹配
答:可以不匹配严拒,但是沒(méi)什么用
2、arguments? 參數(shù)什么時(shí)候用
答:我們不知道接收多少參數(shù)的時(shí)候用arguments,存儲(chǔ)方式和數(shù)組 一樣 被稱(chēng)為偽數(shù)組
3竖独、定義函數(shù)有那2種方式
答: 函數(shù)表達(dá)式var a = function(){} 和函數(shù) 聲明? function fn(){}
4裤唠、js 變量安卓作用域,分為哪兩種變量
答:全局變量 和局部變量 莹痢,局部變量外面不能用,在局部?jī)?nèi)沒(méi)有使用var 的是全局變量
5种蘸、js 解釋器 運(yùn)行js 分為 那兩步
答:預(yù)解析 和代碼執(zhí)行 ,先把 變量 和函數(shù) 提升 然后開(kāi)始運(yùn)行竞膳, 預(yù)解析 提升到當(dāng)前作用域航瞭,什么叫做當(dāng)前作用域就是就是函數(shù)內(nèi)部的 提升到函數(shù)內(nèi)部