keywords:函數(shù)聲明、函數(shù)表達(dá)式举塔、聲明前置绑警、argument、重載央渣、作用域鏈
-
函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別计盒?
函數(shù)聲明:
function functionName() {
statement;
}
使用function關(guān)鍵字可以聲明一個(gè)函數(shù)。
函數(shù)表達(dá)式:
var functionName = function() {
statement;
};
將函數(shù)賦給一個(gè)變量芽丹,變量將會(huì)指向函數(shù)北启,下次使用直接調(diào)用變量即可。
-
什么是變量的聲明前置志衍?什么是函數(shù)的聲明前置暖庄?
變量的聲明前置:
console.log(a);
var a=1;
//undefined
/*實(shí)際上相當(dāng)于:
var a ;
console.log(a);
a=1;
變量會(huì)提升到最前面;
*/
函數(shù)的聲明前置:
fn();
//"1"
function fn() {
console.log('1');
}
//實(shí)際上楼肪,和變量聲明一樣培廓,函數(shù)聲明會(huì)提升到最前面,但會(huì)在變量聲明的后面。
-
arguments 是什么春叫?
在函數(shù)內(nèi)部,你可以使用arguments對(duì)象獲取到該函數(shù)的所有傳入?yún)?shù)肩钠。類似于數(shù)組泣港。
function printPersonInfo(name, age, sex){
console.log(name);
console.log(age);
console.log(sex);
console.log(arguments);
}
-
函數(shù)的重載怎樣實(shí)現(xiàn)?
重載价匠,即相同函數(shù)名的參數(shù)個(gè)數(shù)不同或順序不同当纱,被視為不同的函數(shù)。 在JS中沒有函數(shù)重載的概念踩窖,函數(shù)的名稱具有唯一性坡氯,參數(shù)不同或順序不同也被認(rèn)為是同一函數(shù)。
function sum (a,b) {
return a+b;
}
function sum (a,b,c){
return a+b+c;
}
//如果重載洋腮,則這兩個(gè)函數(shù)不同箫柳;
但在JS中可以利用遍歷arguments模仿重載的功能。例如求和:
function sum() {
var val = 0;
for (var i=0;i<arguments.length;i++) {
val += arguments[i];
}
}
-
立即執(zhí)行函數(shù)表達(dá)式是什么啥供?有什么作用?
立即執(zhí)行函數(shù)表達(dá)式悯恍,簡稱IIFE,是指定義一個(gè)函數(shù)之后伙狐,立刻調(diào)用函數(shù)涮毫。常用的寫法有兩種:
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
JavaScript引擎規(guī)定,如果function關(guān)鍵字出現(xiàn)在行首贷屎,一律解釋成語句罢防。因此,JavaScript引擎看到行首是function關(guān)鍵字之后豫尽,會(huì)認(rèn)為這一段都是函數(shù)的定義篙梢。
如果要立即執(zhí)行函數(shù)顷帖,解決方法就是不要讓function出現(xiàn)在行首美旧,讓引擎將其理解成一個(gè)表達(dá)式。
通常只對(duì)匿名函數(shù)使用IIFE贬墩,主要的作用是:
1榴嗅、不必為函數(shù)命名,污染全局變量陶舞;
2嗽测、在函數(shù)內(nèi)部形成單獨(dú)作用域,封裝外部無法讀取的私有變量肿孵;
參考:
詳解JavaScript立即執(zhí)行函數(shù)表達(dá)式
JavaScript的立即執(zhí)行函數(shù)
-
什么是函數(shù)的作用域鏈唠粥?
JavaScript的每個(gè)函數(shù)function都有自己的作用域,使用Active Object(簡稱AO)活動(dòng)對(duì)象來保存停做,在相互嵌套的函數(shù)中形成了作用域鏈晤愧,如下圖所示:
作用域鏈就是從里到外的AO鏈。
函數(shù)fn3中使用的變量蛉腌,如在fn3作用域?qū)ふ也坏焦俜荩瑒t往外層fn作用域?qū)ふ抑焕澹源祟愅疲钡饺謱?duì)象window舅巷。
例如:
var c = 5;
function t1(){
var d = 6;
function t2(){
var e = 7;
var d = 3;
//如果在這里聲明的var d = 3羔味,
//那么函數(shù)就不在向外尋找變量d,輸出的值為15
console.log(c+d+e);
}
t2();
}
t1();
再如:
var a = 1
function fn1() {
console.log(a)
var a = 5
function fn2() {
console.log(a)
a = 20
d = 10
}
a++
fn2()
console.log(a)
console.log(d)
}
fn1()
console.log(a)
console.log(d)
//undefined
//6
//20
//10
//1
//10
參考:
JavaScript.the core
深入理解JavaScript——作用域鏈
代碼
-
以下代碼輸出什么?
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('男');
//name: hunger
//age: 28
//sex: 男
//['hunger', 28, '男']
//name valley
//name: hunger
//age: 28
//sex: undefined
//['hunger', 28]
//name valley
//name: 男
//age: undefined
//sex: undefined
//['hunger']
//name valley
-
寫一個(gè)函數(shù)钠右,返回參數(shù)的平方和赋元?如
function sumOfSquares(){
var val = 0;
for (var i=0,length=arguments.length; i<length;i++) {
val += arguments[i]*arguments[i]
}
return console.log(val);
}
sumOfSquares(2,3,4); // 29
sumOfSquares(1,3); // 10
-
如下代碼的輸出?為什么
console.log(a); //變量聲明前置
var a = 1;
console.log(b); //b未定義
//undefined
//報(bào)錯(cuò)
-
如下代碼的輸出飒房?為什么
sayName('world'); //函數(shù)聲明前置
sayAge(10); //函數(shù)表達(dá)式不能前置
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
//hello world
//TypeError : sayAge is not a function
-
.如下代碼的輸出们陆?為什么
function fn(){}
var fn = 3; //變量聲明前置,fn先是函數(shù)情屹,后被賦予數(shù)值3坪仇;
console.log(fn);
//3
-
如下代碼的輸出?為什么
function fn(fn2){
console.log(fn2);
var fn2 = 3;
console.log(fn2);
console.log(fn);
function fn2(){
console.log('fnnn2');
}
}
fn(10);
//function fn2()
//3
//function fn()
//上述函數(shù)相當(dāng)于:
//function fn(fn2){
// var fn2;
// function fn2(){
// console.log('fnnn2');
// }
// console.log(fn2);
// fn = 3;
// console.log(fn2);
// console.log(fn);
//}
-
如下代碼的輸出垃你?為什么
var fn = 1;
function fn(fn){
console.log(fn);
}
console.log(fn(fn));
//TypeError: fn is not a function
//實(shí)際上椅文,相當(dāng)于:
//var fn;
//function fn(fn){
// console.log(fn);
//}
//fn = 1;
//console.log(fn(fn));
-
如下代碼的輸出?為什么
//作用域
console.log(j);
console.log(i);
for(var i=0; i<10; i++){ //i和j變量聲明前置惜颇,i和j是全局變量
var j = 100;
}
console.log(i);
console.log(j);
//undefined
//undefined
//10
//100
-
如下代碼的輸出皆刺?為什么
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;
}
}
//undefined
//100
//10
// 實(shí)際上,相當(dāng)于:
// var i;
// var fn;
// function fn(){
// var i;
// function fn2(){
// i = 100; 這里i是全局變量凌摄;
// }
// console.log(i);
// i = 99;
// fn2();
// console.log(i);
// }
// fn();
// i = 10;
// fn = 20;
// console.log(i);
-
如下代碼的輸出羡蛾?為什么
var say = 0;
(function say(n){
console.log(n);
if(n<3) return;
say(n-1);
}( 10 ));
console.log(say);
// 10
// 9
// 8
// 7
// 6
// 5
// 4
// 3
// 2
// 0
//這里用到立即執(zhí)行函數(shù)表達(dá)式(IIFE),say不斷執(zhí)行锨亏,直到遇到return跳出函數(shù)痴怨,
//之后函數(shù)say被銷毀,say成為0