函數聲明和函數表達式的區分
函數聲明:function functionName(){ statement; }
函數表達式:var printName = function(){ console.log('Byron'); };
關於函數聲明,js剖析器會優先讀取(與變量提拔相似,全部函數聲明也會預先剖析
),確保在一切代碼實行之前聲明已被剖析。而函數表達式,犹如定義別的基礎範例的變量一樣,定義變量名和賦值分兩個階段,定義變量名被提拔,函數賦值歷程並沒有一同被提拔。具體表如今,當運用函數聲明的情勢來定義函數時,可將挪用語句寫在函數聲明之前,而函數表達式,挪用語句寫函數表達式前面會失足。當聲明統一稱號的函數和變量時,變量聲明在函數聲明前面,背面的函數聲明會掩蓋前面變量的聲明。假如一個函數的聲明被括號括起來,此時是一個語句,函數聲明不會被提拔(前置)由於JavaScript的這一奇異的“特徵”,我們在函數內部定義變量時,請嚴格遵守“在函數內部起首說明一切變量”這一劃定規矩。最常見的做法是用一個var說明函數內部用到的一切變量
變量,函數的聲明前置
1.變量前置就是把變量的聲明提前到當前作用域的最前面,但變量的賦值依然依據本來的遞次實行,假如變量聲明但未被賦值,變量會自動賦值為undefined。
2.函數的聲明前置有兩種狀況,一個是運用函數聲明,則全部聲明都前置,而且會被前置到變量聲明的背面;另一個是運用函數表達式,那末劃定規矩和變量的聲明前置一樣。
代碼示例:
console.log(a); //undefined 聲明變量,變量提拔 var a,還未實行賦值,所以a為undefined
var a = 1; //a=1; 實行變量賦值,a=1;
console.log(b); //b is not defined b未聲明
// 以函數聲明體式格局定義函數,函數聲明提拔,挪用函數的語句可寫在函數聲明語句前
sayName('world')
function sayName(name){
console.log('hello ', name);
}
sayAge(10); //sayAge is not a function 以函數表達式體式格局定義函數,相似變量提拔,var sayAge為undefined所以挪用函數時提醒不是函數
var sayAge = function(age){
console.log(age);
};
同名變量提拔
function fn(){} //先變量提拔var fn,再函數提拔var fn=function(){},由於同名所以此時函數提拔掩蓋變量提拔,fn為函數
var fn = 3; //fn=3,此時fn的值為3
console.log(fn); //輸出3
函數的arguments
函數中默許的arguments對象是獵取的函數在實行中傳遞進函數的現實參數。arguments只在函數內部起作用,而且永久指向當前函數的挪用者傳入的一切參數。arguments相似Array即類數組對象,但它不是一個Array。縱然函數不定義任何參數,arguments照樣能夠拿到參數的值。arguments常用來檢測傳遞進函數的參數個數。類數組對象轉數組運用Array.prototype.slice.call(arguments)要領。
代碼示例:
返回參數平方和
function sumOfSquares(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum=sum+arguments[i]*arguments[i];
}
return sum;
}
sumOfSquares(2,3,4); // 29
sumOfSquares(1,3); // 10
JS函數的重載
在靜態語言中雷同名字的函數,假如其參數個數差別或許參數遞次差別都被認為是差別的函數,稱為函數重載。在JavaScript中沒有函數重載的觀點,函數經由過程名字肯定唯一性,參數差別也被認為是雷同的函數,背面的掩蓋前面的。JS函數重載用arguments來遍歷傳遞進函數的參數,依據參數的值來實行差別的代碼。
馬上實行函數的作用
函數馬上實行,先括號聲明函數然後括號挪用函數。(function(){ })( )
(函數聲明)(函數挪用)或許(function( ){ }( ))
馬上實行函數表達式平常不需要給函數定名,由於只需要馬上實行並返回一個效果就行。函數馬上實行的作用:
1.沒必要為函數定名,避免了污染全局變量,馬上實行完成后被內存接納。
2.IIFE內部構成了一個零丁的作用域(由於加了括號成為了一個語句),能夠封裝一些外部沒法讀取的私有變量
什麼是函數的作用域鏈
1.在大多數語言中都是用花括號{}來構成一個作用域,俗稱塊作用域,但是在JavaScript中{ }並沒有帶來塊作用域(ES6除外)。ES5中作用域分全局作用域和函數作用域,函數作用域內定義的變量函數外不能夠接見。
2.函數內聲明變量加var代表局部變量,假如函數內聲明變量不加var,則聲明變量是全局變量。全局作用域的變量現實上是被綁定到window的一個屬性。
3.由於JavaScript的函數能夠嵌套,此時,內部函數能夠接見外部函數定義的變量,反過來則不可。任何變量(函數也視為變量),假如沒有在當前函數作用域中找到,就會繼承往上查找,末了假如在全局作用域中也沒有找到,則報ReferenceError毛病。JavaScript的函數在查找變量時從本身函數定義最先,從“內”向“外”查找。假如內部函數定義了與外部函數重名的變量,則內部函數的變量將“屏障”外部函數的變量。
'use strict';
function foo() {
var x = 1;
function bar() {
var y = x + 1; // bar能夠接見foo的變量x!
}
var z = y + 1; // ReferenceError! foo不能夠接見bar的變量y!
}