函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別
//函數(shù)聲明
function test1(){}
//函數(shù)表達(dá)式
var test2 = function(){}
函數(shù)聲明可以在在代碼中任意位置調(diào)用任内,但是函數(shù)表達(dá)式只能在表達(dá)式語句后面調(diào)用
什么是變量的聲明前置?什么是函數(shù)的聲明前置
聲明變量后融柬,變量提升到其所處作用域的頂部
console.log(a)//undefined 其實(shí)a已經(jīng)前置了死嗦,只不過還沒有賦值
var a = 5
函數(shù)的聲明前置,提升到其所處作用域的頂部
fn()//調(diào)用雖然在前面粒氧,但是函數(shù)聲明的方法已經(jīng)提升到頂部了越除,就能讓調(diào)用正常運(yùn)行
function fn() {}
如果用了函數(shù)表達(dá)式,那就不能在隨意位置調(diào)用了
fn()//報(bào)錯(cuò)外盯!
var fn = function() {}//此時(shí)的fn身份只是一個(gè)變量值摘盆,這個(gè)時(shí)候在它之前調(diào)用就會(huì)報(bào)錯(cuò)啦
arguments 是什么
是一個(gè)類數(shù)組對象,它包含了函數(shù)中的所有實(shí)際參數(shù)饱苟。
function foo(a,b) {
console.log(arguments);
}
foo(1,2);//[1, 2]
函數(shù)的"重載"怎樣實(shí)現(xiàn)
其他語言能實(shí)現(xiàn)的“重載”寫法在js這兒是行不通的骡澈,因?yàn)橥暮瘮?shù)會(huì)被覆蓋掉,但是也不是一點(diǎn)兒辦法也沒有掷空,我們可以通過對函數(shù)傳入的參數(shù)進(jìn)行判斷,來實(shí)現(xiàn)同一方法的囤锉,不同處理坦弟,得到不同的結(jié)果,達(dá)到重載的目的官地。
//舉個(gè)栗子
function animals(dog,cat,pig){
if(dog){
console.log(' This is a dog ')
}
if(cat){
console.log(' This is a cat ')
}
if(pig){
console.log(' This is a pig ')
}
}
立即執(zhí)行函數(shù)表達(dá)式是什么酿傍?有什么作用
作用:隔離作用域,避免變量污染全局驱入,將函數(shù)按表達(dá)式的方法寫赤炒,也可達(dá)到這個(gè)效果
(function fn1(){}) ()
求n!,用遞歸來實(shí)現(xiàn)
//遞歸亏较,寫個(gè)方法莺褒,自己調(diào)用自己,就叫遞歸
function recursion(n){
if(typeof n !='number'){
console.log('請輸入數(shù)字')
return
}
else if(n===0){
console.log('不能輸入0的啊')
return
}
else if(n===1){
return 1
}
else{
return n * recursion(n-1)
}
}
以下代碼輸出什么雪情?
function getInfo(name, age, sex){
console.log('name:',name);
console.log('age:', age);
console.log('sex:', sex);
console.log(arguments);
arguments[0] = 'valley';
console.log('name', name);
}
getInfo('饑人谷', 2, '男'); //name:饑人谷 age:2 sex:男 ['饑人谷',2,'sex'] name valley
getInfo('小谷', 3); //name:小谷遵岩、age:3、undefined、['小谷', 3]尘执、name vally;
getInfo('男'); //name:男舍哄、undefined、undefined誊锭、['男']表悬、name vally;
寫一個(gè)函數(shù),返回參數(shù)的平方和丧靡?
function sumOfSquare(){
result = 0
for(var i =0;i<arguments.length;i++){
result = result + arguments[i]*arguments[i]
}
return result
}
console.clear()
console.log(sumOfSquare(5,5))//50
如下代碼的輸出?為什么
console.log(a);//變量提升的原因窘行,讀到了代碼,但是輸出早了沒來得及給值但绕,所以是undefined
var a = 1;
console.log(b);//這個(gè)b壓根兒就不存在惶看,所以就是b is not defined
如下代碼的輸出?為什么
sayName('world');//hello,world,變量提升幅骄,隨意調(diào)用拆座,都可得值
sayAge(10);//sayAge is not a function冠息,表達(dá)式的寫法,使這個(gè)方法只能以“值”的形式存在躏碳,沒有“提升”的特權(quán)散怖,所以此時(shí)的調(diào)用就報(bào)錯(cuò)
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
}
如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
//輸出10
偽代碼展示
// 變量提升镇眷,激活上下文之后等同于:
var x = 10
function foo() {
console.log(x)
}
bar()
// 最后輸出10
我的想法:這兩個(gè)方法是沒有包含和被包含關(guān)系的,都是一旦被激活丹诀,先找自己方法內(nèi)的小范圍,如果找不到就順延著去全局找去硝桩,不要因?yàn)閒oo方法在bar范圍內(nèi)激活的就認(rèn)為這兩個(gè)方法有包含從屬關(guān)系
如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
//輸出30
偽代碼展示
// 變量提升碗脊,激活上下文之后等同于:
var x = 30;
function foo(){
console.log(x)
}
我的想法:上面一題那種寫法橄妆,兩個(gè)方法是沒有 從屬包含 關(guān)系的,但是這一題的寫法是有 從屬包含關(guān)系的矢劲,主要的不同點(diǎn)在與foo方法的循跡范圍出現(xiàn)了變化 它找東西的過程是這樣的 先找自己范圍內(nèi)的慌随,若沒有,找bar方法有沒有丸逸,若bar方法沒有剃袍,馬上就去全局去找去,這個(gè)是與上一題最大的不同
以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
//輸出30
偽代碼展示
// 變量提升憔维,激活上下文之后等同于:
var x = 30;
(function (){
console.log(x)
})()
以下代碼輸出什么埋同? 寫出作用域鏈查找過程偽代碼
var a = 1;
function fn(){
console.log(a)
var a = 5
console.log(a)
a++
var a
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
fn()
console.log(a)
//依次輸出 undefined,5,1,6,20.200
全局范圍內(nèi)瀏覽器讀碼讀到了什么
a = 1
名為 fn 的方法
名為 fn3 的方法
當(dāng)讀到fn()時(shí)會(huì)激活fn方法 開始fn函數(shù)的上下文,fn里面讀到了什么
a = undefined
名為 fn2 的方法
console.log(a) // 第一次輸出undefined
a = 5
console.log(a) //第二次輸出 5
a++ //此時(shí)在fn方法中a為6
當(dāng)讀到fn3()時(shí)激活fn3的上下文咧栗,看看fn3里面有點(diǎn)兒啥
瀏覽器第一遍讀碼會(huì)發(fā)現(xiàn)這個(gè)里面沒有可提升的東西,
第二遍讀碼交煞,如果要輸出a就得去全局中去找a,此時(shí)全局中的a
為1 所以第三次輸出1斟或,讀到a = 200時(shí),就把全局中的a=1
改成a=200御毅,此時(shí)全局的a值由開始時(shí)的1變成了200啦
讀完fn3之后,會(huì)激活fn2方法的上下文端蛆,然后看看fn2里面,能讀到什么
瀏覽器進(jìn)入fn2后第一遍讀碼發(fā)現(xiàn)沒有可提升的東西嫌拣,接著第二遍讀碼呆躲,輸出a,fn2的范圍里沒有a灰瞻,便去fn里面找a去燥筷,此時(shí)fn方法里面的a為6然后第四次輸出6,讀到a = 20時(shí)袍祖,就把fn方法里面的a=6改成a=20
把fn2里面的東西都讀完了蕉陋,就該接著讀fn2()下面的代碼了拨扶,讀到console.log(a),此時(shí)fn里面的a值已經(jīng)是20啦缩举,所以現(xiàn)在第五次輸出20匹颤,到這一步,fn里面的東西都已經(jīng)讀完了辽慕,也代表著全局里面的fn()方法折騰完了赦肃。
接著讀fn()方法后面的代碼console.log(a)公浪,接著就得輸出全局中的a此時(shí)a的值為200 所以 第六次輸出就是200啦