問答題
-
函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*)
答://函數(shù)聲明 function hello(){ console.log("hello world"); } //函數(shù)表達(dá)式 var hello = function(){ console.log("hello world"); }
兩種方式都能聲明函數(shù)榴芳,但是函數(shù)聲明的寫法會(huì)將函數(shù)前置算柳,可以在全局種任何地方調(diào)用函數(shù)痪宰;但是表達(dá)式只能前置sayHi變量,如果在表達(dá)式之前調(diào)用函數(shù)則會(huì)報(bào)錯(cuò),只能放在表達(dá)式后面進(jìn)行調(diào)用。
-
什么是變量的聲明前置何址?什么是函數(shù)的聲明前置 (**)
答:- 變量的聲明前置:變量聲明都會(huì)被放在代碼的頭部,只提升變量的聲明并不會(huì)進(jìn)行賦值械念。
//全局中定義變量 var a = 1; var b = 2; //實(shí)際是執(zhí)行起來是這樣的 var a; var b; a = 1; b = 2;
//函數(shù)中 function say(){ var a = 1; console.log(a); var b = 2; } //實(shí)際運(yùn)行過程 function say(){ var a; var b; a = 1; console.log(a); b = 2; }
- 函數(shù)聲明前置:函數(shù)的聲明前置和變量聲明一樣头朱,會(huì)提升到代碼頭部。但是會(huì)提升到變量聲明后面龄减,所以可以在函數(shù)聲明前面調(diào)用函數(shù)项钮。
f(10);//10 此時(shí)該函數(shù)是有效的,且結(jié)果正確 function f(num){ console.log(num); }
相當(dāng)于
function f(num){ cconsole.log(num); } f(10);
-
arguments 是什么 (*)
答:
Arguments是個(gè)類似數(shù)組但不是數(shù)組的對(duì)象希停,說他類似數(shù)組是因?yàn)槠渚邆鋽?shù)組相同的訪問性質(zhì)及方式烁巫,能夠由arguments[n]來訪問對(duì)應(yīng)的單個(gè)參數(shù)的值,并擁有數(shù)組長(zhǎng)度屬性length宠能。還有就是arguments對(duì)象存儲(chǔ)的是實(shí)際 傳遞給函數(shù)的參數(shù)亚隙,而不局限于函數(shù)聲明所定義的參數(shù)列表,而且不能顯式創(chuàng)建 arguments 對(duì)象违崇。
arguments對(duì)象的長(zhǎng)度是由實(shí)參決定的阿弃。
-
函數(shù)的重載怎樣實(shí)現(xiàn) (**)
答:
在JavaScript中沒有函數(shù)重載的概念,函數(shù)通過名字確定唯一性羞延,參數(shù)不同也被認(rèn)為是相同的函數(shù)渣淳,后面的覆蓋前面的。函數(shù)調(diào)用沒必要把所有參數(shù)都傳入伴箩,只要你函數(shù)體內(nèi)做好處理就行入愧,但前提是傳的參數(shù)永遠(yuǎn)被當(dāng)做前幾個(gè)。
-
立即執(zhí)行函數(shù)表達(dá)式是什么?有什么作用 (***)
答:(function(){ //第一種 })(); (function(){ //第二種 }());
作用是:立即執(zhí)行函數(shù)可以避免函數(shù)內(nèi)的變量暴露在全局環(huán)境下棺蛛,避免全局變量的污染怔蚌。可以令其函數(shù)中聲明的變量繞過JavaScript的變量置頂聲明規(guī)則旁赊,還可以避免新的變量被解釋成全局變量或函數(shù)名占用全局變量名的情況桦踊,在函數(shù)內(nèi)部?jī)?nèi)部形成了一個(gè)單獨(dú)的作用域,可以封裝一些外部無法讀取的私有變量终畅。
-
什么是函數(shù)的作用域鏈 (****)
答:
在一個(gè)函數(shù)執(zhí)行過程中如果某個(gè)變量在該函數(shù)自己的作用域中沒有钞钙,那么它會(huì)尋找父級(jí)的作用域,直到全局作用域声离,這樣就形成了一個(gè)作用域鏈。
執(zhí)行ss()時(shí)瘫怜,作用域鏈?zhǔn)牵?ss()->t()->window,所以name是”桶飯"
代碼題
-
以下代碼輸出什么术徊? (難度**)
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('男');
輸出結(jié)果:
形參和實(shí)參的數(shù)量可以不一樣,用arguments可以改變實(shí)參的值鲸湃。
-
寫一個(gè)函數(shù)赠涮,返回參數(shù)的平方和?如 (難度**)
function sumOfSquares(){ var num; for(var i = 0;i<arguments.length;i++){ num = num+arguments[i]*arguments[i]; } return num; } sumOfSquares(2,3,4); // 29 sumOfSquares(1,3);
-
如下代碼的輸出暗挑?為什么 (難度*)
console.log(a); var a = 1; console.log(b); //運(yùn)算過程 var a; console.log(a);//輸出undefined笋除,因?yàn)樽兞刻嵘瑫?huì)把變量a的聲明提升到console.log(a);之前炸裆,當(dāng)console.log(a);執(zhí)行的時(shí)候垃它,變量a還沒有被賦值,所以console.log(a);輸出undefined烹看。 a = 1; console.log(b);//報(bào)錯(cuò)国拇,因?yàn)闆]有變量b。
輸出結(jié)果:
-
如下代碼的輸出惯殊?為什么 (難度*)
sayName('world'); sayAge(10); function sayName(name){ console.log('hello ', name); } var sayAge = function(age){ console.log(age); }; //運(yùn)算過程 //在執(zhí)行上面代碼的時(shí)候會(huì)將函數(shù)的聲明前置酱吝,而函數(shù)表達(dá)式只會(huì)將變量的聲明前置,函數(shù)不會(huì)前置土思。實(shí)際上述代碼在執(zhí)行的時(shí)候會(huì)變成這樣: var sayAge; function sayName(name){ console.log('hello ', name); } sayName('world'); sayAge(10);//sayAge(10);的時(shí)候务热,sayAge只是個(gè)變量不是函數(shù),所以會(huì)報(bào)錯(cuò)己儒。最終會(huì)輸出hello world和報(bào)錯(cuò)崎岂。 sayAge = function(age){ console.log(age); };
-
如下代碼的輸出?為什么 (難度**)
function fn(){} var fn = 3; console.log(fn);//輸出3 //當(dāng)在同一個(gè)作用域內(nèi)定義了名字相同的變量和方法的話址愿,無論其順序如何该镣,變量的賦值會(huì)覆蓋方法的賦值。
-
如下代碼的輸出?為什么 (難度***)
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(){
console.log('fnnn2');
}//函數(shù)聲明前置
console.log(fn2);//log fn2()函數(shù)
fn2 = 3;//賦值
console.log(fn2);//log fn2 此時(shí) fn2是3
console.log(fn);//此作用域找不到 fn损合,向上尋找打印 fn 函數(shù)
}
fn(10);
//函數(shù)執(zhí)行命名有沖突的時(shí)候省艳,函數(shù)執(zhí)行載入順序是變量、函數(shù)嫁审、參數(shù)
```
7. 如下代碼的輸出跋炕?為什么 (難度***)
```
var fn = 1;
function fn(fn){
console.log(fn);
}
console.log(fn(fn));
```
輸出:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-ab080b605e1f5adb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
因?yàn)榻o變量聲明進(jìn)行賦值操作后,同名的變量聲明的優(yōu)先級(jí)會(huì)大于同名函數(shù)聲明律适,會(huì)覆蓋同名的函數(shù)聲明辐烂,所以fn現(xiàn)在是一個(gè)變量不是函數(shù),執(zhí)行函數(shù)fn就會(huì)報(bào)錯(cuò)捂贿。
8. 如下代碼的輸出纠修?為什么 (難度**)
```
//作用域
console.log(j);//輸出undefined,因?yàn)樽兞柯暶髑爸贸琲這時(shí)候還沒有賦值扣草。
console.log(i);//輸出undefined,因?yàn)樽兞柯暶髑爸醚胀溃琷這時(shí)候還沒有賦值辰妙。
for(var i=0; i<10; i++){
var j = 100;
}
console.log(i);//輸出10,因?yàn)閒or循環(huán)語(yǔ)句結(jié)束循環(huán)時(shí)甫窟,i的值是10 密浑。
console.log(j);//輸出100,應(yīng)為變量j的值是100粗井。
```
輸出:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-dad462fcdf2280d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
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,因?yàn)樽兞縤的聲明前置浇衬,但還沒有賦值呆瞻。
i = 99;
fn2();//執(zhí)行函數(shù)fn2,因?yàn)楹瘮?shù)中的變量i沒有加關(guān)鍵字var径玖,所以它是一個(gè)全局變量,它會(huì)把100賦值到函數(shù)fn的變量i痴脾。這時(shí)i=100
console.log(i);//輸出100,因?yàn)樽兞縤的值為100梳星。
}
fn();
i = 10;
fn = 20;
console.log(i);//輸出10赞赖,因?yàn)樽詈笞兞縤的值是10。
```
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-a755443ab6d14c20.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
10. 如下代碼的輸出冤灾?為什么 (難度*****)
```
var say = 0;
(function say(n){ //立即執(zhí)行函數(shù)前域,給函數(shù)初始的參數(shù)n=10,當(dāng)滿足n<3時(shí)韵吨,執(zhí)行say(n-1)匿垄。
console.log(n);//輸出10,9,8,7,6,5,4,3,2,因?yàn)楫?dāng)n=2時(shí),函數(shù)return椿疗。
if(n<3) return;
say(n-1);
}( 10 ));
console.log(say);//輸出0.因?yàn)榱⒓磮?zhí)行函數(shù)say(n)相當(dāng)于創(chuàng)造了一塊私有的作用域漏峰,函數(shù)say(n)內(nèi)部可以訪問外部的變量,而外部環(huán)境不能訪問函數(shù)say(n)內(nèi)部的變量届榄,內(nèi)部定義的變量不會(huì)和外部的變量發(fā)生沖突浅乔,所以變量say一直等于0。