任務17-JS語法,JS基礎2

1.函數(shù)聲明和函數(shù)表達式有什么區(qū)別 ?

1.函數(shù)聲明必須有標識符,也就是常說的函數(shù)名;函數(shù)表達式可以省略函數(shù)名。
2.函數(shù)聲明會提前。
3.ECMAScript規(guī)范中表示,函數(shù)聲明語句可以出現(xiàn)在全局代碼中,或者內嵌在其他函數(shù)中,但是不能出現(xiàn)在循環(huán)、條件判、或者try/finally以及with語句中。
注:其實兩者最重要的區(qū)別就是函數(shù)聲明前置的問題,一定要注意這一點。

2.什么是變量的聲明前置?什么是函數(shù)的聲明前置?

當我們寫出:

    var a = 1;
    function sum(){
      var sum = 0;
      for(var i=0;i<arguments.length;i++){
        sum = sum + arguments[i];
      }
      return sum;
}```
實際上最終會被解析為:
var a;
function sum(){
  var sum = 0;
  for(var i=0;i<arguments.length;i++){
    sum = sum + arguments[i];
  }
  return sum;

}
a = 1```
變量的聲明和函數(shù)的聲明都會被提到最前,順序是先變量聲明,后函數(shù)聲明,后面的聲明會覆蓋前面的聲明。

3.arguments 是什么?

arguments 是JavaScript里的一個內置對象,所有函數(shù)都有屬于自己的一個arguments對象,它包括了函所要調用的參數(shù),即使沒有明確寫出來,也會默認有arguments.
例:

function getInfo(name,age,sex){
       console.log('name:',name);
       console.log('age:',age);
       console.log('sex:',sex);
       console.log(arguments);
       arguments[0] = 'xiaoming';
       console.log('name:',name);
     }
      getInfo('hunger',18,'男');
 }```
name,age,sex分別對應 0,1,2的位置,我們可以通過
``argumengts[0[]= 'xiaoming';``來使所有處于 0 位置的變量為 ‘xiaoming'
##4.函數(shù)的重載怎樣實現(xiàn)?
ECMAscript函數(shù)不能像傳統(tǒng)意義上那樣實現(xiàn)重載,一旦對函數(shù)聲明了兩次,函數(shù)會默認使后者覆蓋前者。我們可以使用其他方式來實現(xiàn)重載效果:

function sum() {
var sum = 0;
for (var !=0;i<arguments.length;i++) {
sum = sum + arguments[i];
}
return sum;
}
console.log(sum(1,2,10));
最后可得:
13```

5.立即執(zhí)行函數(shù)表達式是什么?有什么作用?

function say(){
    console.log("hello");
}
say();```
上面的函數(shù)必須通過``say()``調用后才可以執(zhí)行,``function say(){}``只是聲明這個函數(shù),并沒有執(zhí)行函數(shù)。
我們可以通過對整個函數(shù)加小括號來使函數(shù)聲明變成一個表達式,從而立即執(zhí)行:

(function say(){
console.log("hello");
})();

(function say(){
console.log("hello");
}());

雖然是一個表達式,但是是包裹在函數(shù)中的,此時若在此函數(shù)內加上``var i = 100;``也只會在此表達式內生效,對其他表達式不影響。其作用就是包裹一段代碼,讓這段代碼擁有自己的作用域,要注意的是,這是一個表達式,所以不會前置,而且立即執(zhí)行后,在其他地方也無法調用。
##6.什么是函數(shù)的作用域鏈
首先要明確什么是**作用域**:
作用域就是變量和函數(shù)的可訪問范圍,控制著變量和函數(shù)的可見性與生命周期,在JavaScript中變量的作用域有全局作用域和局部作用域。
**作用域鏈:**
當代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個作用域鏈(scope chain,不簡稱sc)來保證對執(zhí)行環(huán)境**有權**訪問的變量和函數(shù)的**有序**訪問。作用域第一個對象始終是當前執(zhí)行代碼所在環(huán)境的變量對象。

function a(x,y){
var b=x+y; return b;
}```
在函數(shù)a創(chuàng)建的時候它的作用域鏈填入全局對象,全局對象中有所有全局變量.

函數(shù)a的作用域鏈

如果執(zhí)行環(huán)境是函數(shù),那么將其活動對象(activation object, AO)作為作用域鏈第一個對象,第二個對象是包含環(huán)境,依次向其父級作用域尋找變量。

function a(x,y){ 
    var b=x+y; return b; 
    } 
    var tatal=a(5,10);```
此時 ``var tatal=a(5,10);``的作用域如下:

![](http://upload-images.jianshu.io/upload_images/2399926-e1d9a55dbe77d77e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在函數(shù)運行過程中標識符的解析是沿著作用域鏈一級一級搜索的過程,從第一個對象開始,逐級向后回溯,直到找到同名標識符為止,找到后不再繼續(xù)遍歷,找不到就報錯。
***
##代碼:
##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('hunger', 28, '男');
getInfo('hunger', 28);
getInfo('男');


![輸出結果](http://upload-images.jianshu.io/upload_images/2399926-7794d3ef164bb1f1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##2.寫一個函數(shù),返回參數(shù)的平方和

```function sumOfSquares(){
    var sum = 0;
    for(i=0;i<arguments.length;i++){
    sum = sum + arguments[i]*arguments[i];
  }
    console.log(sum);
    return sum;
} 
sumOfSquares(2,3,4); 
sumOfSquares(1,3);```.
##3.如下代碼的輸出?為什么

console.log(a);
var a = 1;
console.log(b);```
變量提升:

var a;
console.log(a);//undefined(因為聲明了 a 但沒有賦值)
a = 1;
console.log(b);//b is not defined(沒有聲明 b)

4.如下代碼的輸出,為什么

sayName('world');
sayAge(10); 
        function sayName(name){ 
            console.log('hello ', name);
 }
         var sayAge = function(age){ 
            console.log(age); 
};```
變量提升:
    function sayName(name){ 
        console.log('hello ', name);

}
var sayAge = function(age){
console.log(age); //這是一個函數(shù)表達式,不會變量前置。
}
sayName('world');
sayAge(10); ```
所以最后輸出:
hello,world
10

5.如下代碼的輸出?為什么

 function fn(){
} 
var fn = 3;
 console.log(fn);

變量提升:

var fn;
function fn(){
}
fn = 3;
console.log(fn);//3

輸出: 3

6.如下代碼的輸出?為什么

 function fn(fn2){ 
    console.log(fn2); 
    var fn2 = 3;
    console.log(fn2); 
    console.log(fn);
 function fn2(){
     console.log('fnnn2');
 } 
} 
 fn(10);```
變量提升:

function fn(fn2){
var fn2;//變量聲明
function fn2(){//函數(shù)聲明
console.log('fnnn2');
}
console.log(fn2);
fn2 = 3;
console.log(fn2);
console.log(fn);
}
fn(10);```
輸出結果:

7.如下代碼的輸出?為什么

var fn = 1; 
function fn(fn){
     console.log(fn);
 } 
     console.log(fn(fn)); 

變量提升:

var fn;
function fn(fn){
     console.log(fn);
}
fn = 1;
     console.log(fn(fn));```
經過變量提升后,fn已經不是一個函數(shù)了,所以輸出``fn is not a function``
##8.如下代碼的輸出?為什么
``` //作用域
    console.log(j); 
    console.log(i); 
for(var i=0; i<10; i++){
       var j = 100;
 } 
    console.log(i);
    console.log(j);```
變量提升:

var j;
var i;
console.log(j);//undefined
console.log(i);//undefined
for(i = 0; i<10;i++){
j =100;
}
console.log(i);//10
console.log(j);//100

for是表達式,不是函數(shù),沒有自己的單獨作用域,所以``var j = 100;``和``var i =0;``會被前置。最后得到:
undefined
undefined
10
100
##9.如下代碼的輸出?為什么
fn();
var i = 10;
var fn = 20;
console.log(i);
function fn(){
    console.log(i);
    var i = 99;
    fn2();
    console.log(i);
    function fn2(){
        i = 100;
    }
}```

變量提升:

var i;
var fn;
function fn(){
          var i;
          function fn2(){
          i= 100;
       }
          console.log(i);//undefined
          i =99;
          fn2( );
          console.log(i);//100
}
fn();
i = 10;
fn = 20;
console.log(i);//10

最后得出:
undefined
100
10

10.如下代碼的輸出?為什么

    var say = 0;
    (function say(n){
        console.log(n);//10
        if(n<3) return;
        say(n-1);//9,8,7,6,5,4,3,2
    }( 10 ));
    console.log(say);//0

此段代碼中的函數(shù)為立即執(zhí)行函數(shù),可以看作是一個表達式,所以不會被前置。若n>3,立刻return輸出say

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答: 1. 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*) 在日常的任務中,JavaScript主要使用下面兩種方式創(chuàng)建...
    小木子2016閱讀 324評論 0 0
  • 一、函數(shù)聲明和函數(shù)表達式有什么區(qū)別?(*) ** 1.ECMAScript里面規(guī)定了三種聲明函數(shù)的方式**①構造函...
    鴻鵠飛天閱讀 471評論 0 0
  • 繼承 一、混入式繼承 二、原型繼承 利用原型中的成員可以被和其相關的對象共享這一特性,可以實現(xiàn)繼承,這種實現(xiàn)繼承的...
    magic_pill閱讀 1,075評論 0 3
  • 1. 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*) 函數(shù)在JS中有三種方式來定義:函數(shù)聲明(function decla...
    進擊的阿群閱讀 453評論 0 1
  • 進度條49 -160 我要把每首詩讀成一個故事。今天這首詩的主角還是那個昏君衛(wèi)宣公。 這是鄘風第五首,全詩共二章。...
    劉小麥同學閱讀 813評論 0 1