1.函數聲明和函數表達式
函數聲明和函數表達式都可以聲明函數,但使用函數聲明的方法,聲明不必放在調用前;使用函數表達式,聲明需要在調用前,可以省略函數名。
例:
function sayHello(){
console.log('hello')
}
//函數聲明
var sayHello = function(){
console.log('hello');
}
//函數表達式
2.變量與函數的聲明前置
在一個作用域下,var聲明的變量和function聲明的函數會前置,聲明的語句會優先執行。
3.arguments 對象
Arguments是個類似數組但不是數組的對象,說他類似數組是因為其具備數組相同的訪問性質及方式,能夠由arguments[n]來訪問對應的單個參數的值,并擁有數組長度屬性length。還有就是arguments對象存儲的是實際 傳遞給函數的參數,而不局限于函數聲明所定義的參數列表,而且不能顯式創建 arguments 對象。
4.函數的"重載"怎樣實現
JavaScript不支持函數的重載,即不能夠定義同樣的函數然后通過編譯器去根據不同的參數執行不同的函數。但可以在函數內部定義多種模式,根據傳進來的參數信息進行匹配。
5.立即執行函數表達式
立即執行函數表達式是一種可以使函數在被定義后立即執行的一種寫法,在javascript里,括號內部不能包含語句,當解析器對代碼進行解釋的時候,先碰到了(),然后碰到function關鍵字就會自動將()里面的代碼識別為函數表達式而不是函數聲明。例如下面的代碼:
(function(){
var a = 1;
})()
console.log(a); //undefined
立即執行函數表達式的作用:一是不必為函數命名,避免了污染全局變量;二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。避免了污染全局變量。
6.求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. 寫一個函數,返回平方和
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,因為函數聲明提前
}
var sayAge = function(age){
console.log(age); //報錯,因為使用函數表達式必須在其后調用,否則認為sayAge不是函數
};
11. 作用域鏈查找過程偽代碼 ,舉例如下:
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
/*****************************************************************************/
//作用域鏈查找過程如下:
//首先全局作用域中聲明的變量有:x,函數有foo(),bar()
globalContext = {
AO:{
x:10
foo:function
bar:function
},
Scope:null
}
//此時被聲明的函數foo(),bar()的scope為 globalContext.AO
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
//繼續執行,進入bar的執行上下文
barContext = {
AO:{
x:30
}
scope:bar.[[scope]] = globalContext.AO
}
//調用foo從scope中找到,進入foo的執行上下文
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,函數bar()
globalContext = {
AO: {
x: 10
bar: function
}
Scope: null
}
//此時被聲明的bar()的scope為globalContext.AO
bar.[[scope]] = globalContext.AO
//進入bar執行上下文
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,函數bar()
globalContext = {
AO: {
x: 10
bar: function
}
Scope: null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30
anonymous:function //匿名函數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