1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別。
- 函數(shù)聲明使用function來進(jìn)行聲明,函數(shù)聲明提升,所以不論執(zhí)行語句的位置皆可調(diào)用該函數(shù)。
- 函數(shù)表達(dá)式通過賦值來聲明函數(shù),聲明完畢后要加上分號(hào)表示該句結(jié)束,在表達(dá)式執(zhí)行完后,函數(shù)才存在并可被調(diào)用。
2.變量提升和函數(shù)提升
所謂的變量聲明前置就是在一個(gè)作用域塊中,所有的變量都被放在塊的開始出聲明。
和變量聲明前置一樣,執(zhí)行代碼之前會(huì)先讀取函數(shù)聲明,只要函數(shù)在代碼中進(jìn)行了聲明,無論它在哪個(gè)位置上進(jìn)行聲明,js引擎都會(huì)將它的聲明放在范圍作用域的頂部。
3.argument
argument是類數(shù)組對(duì)象,每個(gè)函數(shù)中都存在argument對(duì)象,argument并不是一個(gè)真正的數(shù)組,所以不具備除length屬性之外的屬性,這個(gè)對(duì)象維護(hù)這所有傳入該函數(shù)的參數(shù)列表。
通過以下語句可將arguments轉(zhuǎn)化為數(shù)組對(duì)象:
var args=Array.prototype.slice.call(arguments)
4.函數(shù)重載的實(shí)現(xiàn)
在JS中,沒有重載。同名函數(shù)會(huì)覆蓋。但可以在函數(shù)體針對(duì)不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯。
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);//Byron 26
printPeopleInfo('Byron', 26, 'male');//Byron 26 male
5.立即執(zhí)行函數(shù)表達(dá)式是什么?有什么作用?
(function(){ var a = 1; })()
作用: 隔離作用域。因?yàn)镴avaScript中沒有命名空間,而且只有function代碼塊內(nèi)部可以隔離變量作用域,自調(diào)用匿名函數(shù)就用來防止變量彌散到全局,以免各種js庫沖突。
6.用遞歸求n!
function factorial(n){ if(n===1){ return 1; } return n*factorial(n-1); } factorial(3);//6
7.以下代碼輸出什么?
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, "男"]
name valley
getInfo('小谷', 3);
name: 小谷
age: 3
sex: undefined
["小谷", 3]
name valley
getInfo('男');
name: 男
age: undefined
sex: undefined
["男"]
name valley
8.寫一個(gè)函數(shù),返回參數(shù)的平方和?
function sumOfSquares(){ } var result = sumOfSquares(2,3,4) var result2 = sumOfSquares(1,3) console.log(result) //29 console.log(result) //10
function sumOfSquares(){ var sum=0; for(var i=0;i<arguments.length;i++){ sum=sum+arguments[i]*arguments[i]; } console.log(sum); } var result = sumOfSquares(2,3,4) var result2 = sumOfSquares(1,3) console.log(result) //29 console.log(result) //10
9.如下代碼的輸出?為什么?
console.log(a); var a = 1; console.log(b);
- console.log(a)輸出的是undefined。雖然var a聲明了,但是沒有賦值,結(jié)果為undefined.
- console.log(b)完全是沒有聲明也沒有賦值,結(jié)果是報(bào)錯(cuò).//ReferenceError: b is not defined
11. 如下代碼的輸出?為什么?
sayName('world'); sayAge(10); function sayName(name){ console.log('hello ', name); } var sayAge = function(age){ console.log(age); };
hello world
sayAge is not a function(報(bào)錯(cuò))
函數(shù)聲明會(huì)在代碼執(zhí)行前首先讀取,而函數(shù)表達(dá)式要在代碼執(zhí)行到那一句時(shí),才會(huì)函數(shù)才被定義(函數(shù)聲明提升)。
12. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼。
var x = 10 bar() function foo() { console.log(x) } function bar(){ var x = 30 foo() }
1.globalContext = { AO:{ x:10, foo:function, bar:function, }, scope:null; } foo['scope'] = globalContext.AO; bar['scope'] = globalContext.AO; 2.barContext = { AO:{ x:30, }, scope:golbalContext.AO } 3.fooContext = { AO:{}, scope:golbalContext.AO } 輸出10
12. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼。
var x = 10; bar() function bar(){ var x = 30; function foo(){ console.log(x) } foo(); }
1.globalContext = { AO:{ x:10, bar:function, }, scope:null, } bar['scope'] = globalContext.AO; 2.barContext = { AO:{ x:30, foo:function, }, scope: globalContext.AO, } foo.['scope'] = barContext.AO 3.fooContext = { AO:{}, scope:barContext.AO, } 輸出: 30
13.以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼。
var x = 10; bar() function bar(){ var x = 30; (function (){ console.log(x) })() }
1.globalContext = { AO:{ x:10, bar:function, }, scope:null; } bar['scope'] = globalContext.AO; 2.barContext = { AO:{ x:30, foo:function, }, scope:golbalContext.AO } function['scope'] = barContext.AO; 3.functionContext = { AO:{}, scope:barContext.AO } 輸出 30
14.以下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
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)
`1.globalContext = {
AO:{
a:1,
fn:function,
fn3:function,
},
scope:null;
}
fn['scope'] = globalContext.AO;
fn3['scope'] = globalContext.AO;
2.fnContext = {
AO:{
a:undefined,
fn2:function,
},
scope:globalContext.AO
}
fn2['scope'] = fnContext.AO;
3.fn2Context = {
AO:{},
scope:fnContext.AO
}
fn3Context = {
AO:{
a:20
},
scope:globalContext.AO,
}
開始執(zhí)行
console.log(a)//undefined 打印
var a = 5//fnContext中a變成5
console.log(a)//5
a++//fnContext.AO中a變?yōu)?
調(diào)用fn3()
fn3()中
console.log(a)//globalContext.AO中的a值為1,打印
a = 200//globalContext.AO中的a變?yōu)?00
調(diào)用fn2()
console.log(a);//fnContext.AO中的a值為6,打印
a = 20;//fnContext.AO中的a變?yōu)?0
繼續(xù)執(zhí)行fn()
console.log(a)//fnContext.AO中的a值為20,打印
fn()結(jié)束
console.log(a)//globalContext.AO中a值為200,打印
輸出的結(jié)果 undefined 5 1 6 20 200
`