1.函數(shù)聲明和函數(shù)表達式
函數(shù)聲明和函數(shù)表達式都可以聲明函數(shù)恼琼,但使用函數(shù)聲明的方法屏富,聲明不必放在調用前;使用函數(shù)表達式噩死,聲明需要在調用前,可以省略函數(shù)名行嗤。
例:
function sayHello(){
console.log('hello')
}
//函數(shù)聲明
var sayHello = function(){
console.log('hello');
}
//函數(shù)表達式
2.變量與函數(shù)的聲明前置
在一個作用域下垛耳,var聲明的變量和function聲明的函數(shù)會前置,聲明的語句會優(yōu)先執(zhí)行既琴。
3.arguments 對象
Arguments是個類似數(shù)組但不是數(shù)組的對象泡嘴,說他類似數(shù)組是因為其具備數(shù)組相同的訪問性質及方式,能夠由arguments[n]來訪問對應的單個參數(shù)的值磺箕,并擁有數(shù)組長度屬性length抛虫。還有就是arguments對象存儲的是實際 傳遞給函數(shù)的參數(shù)建椰,而不局限于函數(shù)聲明所定義的參數(shù)列表,而且不能顯式創(chuàng)建 arguments 對象棉姐。
4.函數(shù)的"重載"怎樣實現(xiàn)
JavaScript不支持函數(shù)的重載伞矩,即不能夠定義同樣的函數(shù)然后通過編譯器去根據(jù)不同的參數(shù)執(zhí)行不同的函數(shù)。但可以在函數(shù)內部定義多種模式苛让,根據(jù)傳進來的參數(shù)信息進行匹配炮捧。
5.立即執(zhí)行函數(shù)表達式
立即執(zhí)行函數(shù)表達式是一種可以使函數(shù)在被定義后立即執(zhí)行的一種寫法混萝,在javascript里期奔,括號內部不能包含語句浦旱,當解析器對代碼進行解釋的時候颁湖,先碰到了()例隆,然后碰到function關鍵字就會自動將()里面的代碼識別為函數(shù)表達式而不是函數(shù)聲明。例如下面的代碼:
(function(){
var a = 1;
})()
console.log(a); //undefined
立即執(zhí)行函數(shù)表達式的作用:一是不必為函數(shù)命名镰禾,避免了污染全局變量唱逢;二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量备韧。避免了污染全局變量痪枫。
6.求n!,用遞歸來實現(xiàn)
function factor(n){
if(n === 1) {
return 1
}
return n * factor(n-1)
}
var result=factor(5);
console.log(result)
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 undefined ["小谷", 3] name vally
getInfo('男'); //結果: name:男 undefined undefined ["男"] name vally
8. 寫一個函數(shù)吃粒,返回平方和
function sumOfSquares(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum=sun+arguments[i]*arguments[i]
return sum;
}
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result2) //10
9. 如下代碼的輸出徐勃?
console.log(a); //輸出undefined,因為變量a聲明提前很魂,但此時還未被賦值
var a = 1;
console.log(b); //報錯“b is not defined”檐涝,因為b未被聲明
10. 如下代碼的輸出?
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name); //輸出hello world幅聘,因為函數(shù)聲明提前
}
var sayAge = function(age){
console.log(age); //報錯窃植,因為使用函數(shù)表達式必須在其后調用,否則認為sayAge不是函數(shù)
};
11. 作用域鏈查找過程偽代碼 葛超,舉例如下:
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
/*****************************************************************************/
//作用域鏈查找過程如下:
//首先全局作用域中聲明的變量有:x,函數(shù)有foo(),bar()
globalContext = {
AO:{
x:10
foo:function
bar:function
},
Scope:null
}
//此時被聲明的函數(shù)foo(),bar()的scope為 globalContext.AO
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
//繼續(xù)執(zhí)行答渔,進入bar的執(zhí)行上下文
barContext = {
AO:{
x:30
}
scope:bar.[[scope]] = globalContext.AO
}
//調用foo從scope中找到沼撕,進入foo的執(zhí)行上下文
fooContext = {
AO:{
}
scope:foo.[[scope]] = globalContext.AO
}
//從foo的scope:globalContext.AO中找到x:10芜飘,所以輸出10。
輸出10
12. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
/***********************************************************************/
//全局作用域中聲明變量x,函數(shù)bar()
globalContext = {
AO: {
x: 10
bar: function
}
Scope: null
}
//此時被聲明的bar()的scope為globalContext.AO
bar.[[scope]] = globalContext.AO
//進入bar執(zhí)行上下文
barContext = {
AO: {
x: 30
foo: function
}
Scope: bar.[[scope]] = globalContext.AO
}
//foo()被聲明笼沥,它的scope為barContext.AO
foo.[[scope]] = barContext.AO
fooContext = {
AO: { }
Scope: foo.[[scope]] = barContext.AO
}
輸出為30
13. 以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
/************************************************************************************************/
//全局作用域聲明變量x敬拓,函數(shù)bar()
globalContext = {
AO: {
x: 10
bar: function
}
Scope: null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30
anonymous:function //匿名函數(shù)anonymous
}
Scope: bar.[[scope]] = globalContext.AO
}
anonymous.[[scope]] = barContext.AO
anonymousContext = {
AO: { }
Scope: anonymous.[[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)
/************************************************************************************************/
globalContext = {
AO: {
a: 1
fn: function
fn3: function
}
Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO
fnContext = {
AO: {
a: undefined
fn2: function
}
Scope: fn.[[scope]] = globalContext.AO
}
fn2.[[scope]] = fnContext.AO
//進入fn后先輸出undefined累榜,a賦值為5后輸出5
fn3Context = {
AO: {}
Scope: fn3.[[scope]] = globalContext.AO
}
//輸出:1
fn2Context = {
AO: {}
Scope: fn2.[[scope]] = fnContext.AO
}
console.log(a) //輸出200
最后結果為:undefined 5 1 6 200