作用域(重點(diǎn))
- 什么是作用域帕识,就是一個(gè)變量可以生效的范圍
- 變量不是在所有地方都可以使用的窍育,而這個(gè)變量的使用范圍就是作用域
全局作用域
全局作用域是最大的作用域
在全局作用域中定義的變量可以在任何地方使用
頁(yè)面打開(kāi)的時(shí)候,瀏覽器會(huì)自動(dòng)給我們生成一個(gè)全局作用域
window
-
這個(gè)作用域會(huì)一直存在锻弓,直到頁(yè)面關(guān)閉就銷(xiāo)毀了
// 下面兩個(gè)變量都是存在在全局作用域下面的砾赔,都是可以在任意地方使用的 var num = 100 var num2 = 200
局部作用域
局部作用域就是在全局作用域下面有開(kāi)辟出來(lái)的一個(gè)相對(duì)小一些的作用域
在局部作用域中定義的變量只能在這個(gè)局部作用域內(nèi)部使用
在
JS
中只有函數(shù)能生成一個(gè)局部作用域蝌箍,別的都不行-
每一個(gè)函數(shù)青灼,都是一個(gè)局部作用域
// 這個(gè) num 是一個(gè)全局作用域下的變量 在任何地方都可以使用 var num = 100 function fn() { // 下面這個(gè)變量就是一個(gè) fn 局部作用域內(nèi)部的變量 // 只能在 fn 函數(shù)內(nèi)部使用 var num2 = 200 } fn()
變量使用規(guī)則(重點(diǎn))
- 有了作用域以后暴心,變量就有了使用范圍,也就有了使用規(guī)則
- 變量使用規(guī)則分為兩種杂拨,訪問(wèn)規(guī)則 和 賦值規(guī)則
訪問(wèn)規(guī)則
當(dāng)我想獲取一個(gè)變量的值的時(shí)候专普,我們管這個(gè)行為叫做 訪問(wèn)
-
獲取變量的規(guī)則:
- 首先,在自己的作用域內(nèi)部查找弹沽,如果有檀夹,就直接拿來(lái)使用
- 如果沒(méi)有,就去上一級(jí)作用域查找策橘,如果有炸渡,就拿來(lái)使用
- 如果沒(méi)有,就繼續(xù)去上一級(jí)作用域查找丽已,依次類(lèi)推
- 如果一直到全局作用域都沒(méi)有這個(gè)變量蚌堵,那么就會(huì)直接報(bào)錯(cuò)(該變量 is not defined)
var num = 100 function fn() { var num2 = 200 function fun() { var num3 = 300 console.log(num3) // 自己作用域內(nèi)有,拿過(guò)來(lái)用 console.log(num2) // 自己作用域內(nèi)沒(méi)有沛婴,就去上一級(jí)吼畏,就是 fn 的作用域里面找,發(fā)現(xiàn)有嘁灯,拿過(guò)來(lái)用 console.log(num) // 自己這沒(méi)有泻蚊,去上一級(jí) fn 那里也沒(méi)有,再上一級(jí)到全局作用域丑婿,發(fā)現(xiàn)有性雄,直接用 console.log(a) // 自己沒(méi)有,一級(jí)一級(jí)找上去到全局都沒(méi)有羹奉,就會(huì)報(bào)錯(cuò) } fun() } fn()
變量的訪問(wèn)規(guī)則 也叫做 作用域的查找機(jī)制
-
作用域的查找機(jī)制只能是向上找毅贮,不能向下找
function fn() { var num = 100 } fn() console.log(num) // 發(fā)現(xiàn)自己作用域沒(méi)有,自己就是全局作用域尘奏,沒(méi)有再上一級(jí)了滩褥,直接報(bào)錯(cuò)
賦值規(guī)則
當(dāng)你想給一個(gè)變量賦值的時(shí)候,那么就先要找到這個(gè)變量炫加,在給他賦值
-
變量賦值規(guī)則:
- 先在自己作用域內(nèi)部查找瑰煎,有就直接賦值
- 沒(méi)有就去上一級(jí)作用域內(nèi)部查找,有就直接賦值
- 還沒(méi)有再去上一級(jí)作用域查找俗孝,有就直接賦值
- 如果一直找到全局作用域都沒(méi)有酒甸,那么就把這個(gè)變量定義為全局變量,再給他賦值
function fn() { num = 100 } fn() // fn 調(diào)用以后赋铝,要給 num 賦值 // 查看自己的作用域內(nèi)部沒(méi)有 num 變量 // 就會(huì)向上一級(jí)查找 // 上一級(jí)就是全局作用域插勤,發(fā)現(xiàn)依舊沒(méi)有 // 那么就會(huì)把 num 定義為全局的變量,并為其賦值 // 所以 fn() 以后,全局就有了一個(gè)變量叫做 num 并且值是 100 console.log(num) // 100
遞歸函數(shù)
什么是遞歸函數(shù)
在編程世界里面农尖,遞歸就是一個(gè)自己調(diào)用自己的手段
-
遞歸函數(shù): 一個(gè)函數(shù)內(nèi)部析恋,調(diào)用了自己,循環(huán)往復(fù)
// 下面這個(gè)代碼就是一個(gè)最簡(jiǎn)單的遞歸函數(shù) // 在函數(shù)內(nèi)部調(diào)用了自己盛卡,函數(shù)一執(zhí)行助隧,就調(diào)用自己一次,在調(diào)用再執(zhí)行滑沧,循環(huán)往復(fù)并村,沒(méi)有止盡 function fn() { fn() } fn()
其實(shí)遞歸函數(shù)和循環(huán)很類(lèi)似
需要有初始化,自增滓技,執(zhí)行代碼哩牍,條件判斷的,不然就是一個(gè)沒(méi)有盡頭的遞歸函數(shù)令漂,我們叫做 死遞歸
簡(jiǎn)單實(shí)現(xiàn)一個(gè)遞歸
我們先在用遞歸函數(shù)簡(jiǎn)單實(shí)現(xiàn)一個(gè)效果
-
需求: 求 1 至 5 的和
- 先算 1 + 2 得 3
- 再算 3 + 3 得 6
- 再算 6 + 4 得 10
- 再算 10 + 5 得 15
- 結(jié)束
-
開(kāi)始書(shū)寫(xiě)姐叁,寫(xiě)遞歸函數(shù)先要寫(xiě)結(jié)束條件(為了避免出現(xiàn) “死遞歸”)
function add(n) { // 傳遞進(jìn)來(lái)的是 1 // 當(dāng) n === 5 的時(shí)候要結(jié)束 if (n === 5) { return 5 } } add(1)
-
再寫(xiě)不滿足條件的時(shí)候我們的遞歸處理
function add(n) { // 傳遞進(jìn)來(lái)的是 1 // 當(dāng) n === 5 的時(shí)候要結(jié)束 if (n === 5) { return 5 } else { // 不滿足條件的時(shí)候,就是當(dāng)前數(shù)字 + 比自己大 1 的數(shù)字 return n + add(n + 1) } } add(1)
簡(jiǎn)單了解對(duì)象
對(duì)象是一個(gè)復(fù)雜數(shù)據(jù)類(lèi)型
-
其實(shí)說(shuō)是復(fù)雜洗显,但是沒(méi)有很復(fù)雜外潜,只不過(guò)是存儲(chǔ)了一些基本數(shù)據(jù)類(lèi)型的一個(gè)集合
var obj = { num: 100, str: 'hello world', boo: true }
這里的
{}
和函數(shù)中的{}
不一樣函數(shù)里面的是寫(xiě)代碼的,而對(duì)象里面是寫(xiě)一些數(shù)據(jù)的
對(duì)象就是一個(gè)鍵值對(duì)的集合
{}
里面的每一個(gè)鍵都是一個(gè)成員也就是說(shuō)挠唆,我們可以把一些數(shù)據(jù)放在一個(gè)對(duì)象里面处窥,那么他們就互不干擾了
其實(shí)就是我們準(zhǔn)備一個(gè)房子,把我們想要的數(shù)據(jù)放進(jìn)去玄组,然后把房子的地址給到變量名滔驾,當(dāng)我們需要某一個(gè)數(shù)據(jù)的時(shí)候,就可以根據(jù)變量名里面存儲(chǔ)的地址找到對(duì)應(yīng)的房子俄讹,然后去房子里面找到對(duì)應(yīng)的數(shù)據(jù)
創(chuàng)建一個(gè)對(duì)象
字面量的方式創(chuàng)建一個(gè)對(duì)象
// 創(chuàng)建一個(gè)空對(duì)象
var obj = {}
// 像對(duì)象中添加成員
obj.name = 'Jack'
obj.age = 18
內(nèi)置構(gòu)造函數(shù)的方式創(chuàng)建對(duì)象
// 創(chuàng)建一個(gè)空對(duì)象
var obj = new Object()
// 向?qū)ο笾刑砑映蓡T
obj.name = 'Rose'
obj.age = 20
Object是
js` 內(nèi)置給我們的構(gòu)造函數(shù)哆致,用于創(chuàng)建一個(gè)對(duì)象使用的
構(gòu)造函數(shù)
構(gòu)造函數(shù)就是一個(gè)普通的函數(shù),但是有自己的特征和用法患膛。
強(qiáng)化練習(xí)1
利用遞歸求100的階乘
利用遞歸求斐波那契數(shù)列
1摊阀、1、2踪蹬、3胞此、5、8跃捣、13漱牵、21、34疚漆、55……
F(0)=1酣胀,F(xiàn)(1)=1, F(n)=F(n-1)+F(n-2)(n>=2刁赦,n∈N*)
利用遞歸求兩個(gè)數(shù)的最大公約數(shù)(利用輾轉(zhuǎn)相除法)
強(qiáng)化練習(xí)2
編寫(xiě)一個(gè)函數(shù),輸入n為偶數(shù)時(shí)闻镶,調(diào)用函數(shù)求1/2+1/4+...+1/n,當(dāng)輸入n為奇數(shù)時(shí)甚脉,調(diào)用函數(shù)求1+1/3+...+1/n
使用函數(shù)完成任意數(shù)字階乘的計(jì)算
要求:頁(yè)面輸入任意數(shù)字,點(diǎn)擊按鈕后計(jì)算階乘