好家伙,本篇為《JS高級程式設計》第十章“函式”學習筆記
1.函式的三種定義方式:函式運算式、函式宣告及箭頭函式
函式宣告:
function sum(a) {
return a + 1;
}
函式運算式:
let sum= function(a){
return a + 1;
}
箭頭函式:
let sum = (a) => {
return a + 1;
}
以函式宣告方式宣告的函式存在"函式宣告提升",
在執行代碼時,JavaScript 引擎會先執行一遍掃描, 把發現的函式宣告提升到源代碼樹的頂部,
因此即使函式定義出現在呼叫它們的代碼之后,引擎也會把 函式宣告提升到頂部,
而函式運算式這么做會報錯(箭頭函式同樣報錯)

代碼如果沒有執行到函式運算式的那一行,那么執行背景關系中就沒有函式的定義
2.函式名
函式名是指向函式的指標,所以它們跟其他包含物件指標的變數具有相同的行為,
function sum(num1, num2) { return num1 + num2; } console.log(sum(10, 10)); // 20
let anotherSum = sum;
console.log(anotherSum(10, 10)); // 20
sum = null;
console.log(anotherSum(10, 10)); // 20
以上代碼定義了一個名為 sum()的函式,用于求兩個數之和,
然后又宣告了一個變數 anotherSum, 并將它的值設定為等于 sum,
注意,使用不帶括號的函式名會訪問函式指標,而不會執行函式,
此時, anotherSum 和 sum 都指向同一個函式,
呼叫 anotherSum()也可以回傳結果,把 sum 設定為 null 之后,就切斷了它與函式之間的關聯,
而 anotherSum()還是可以照常呼叫,沒有問題,(有意思,之前不清楚)
ECMAScript 6 的所有函式物件都會暴露一個只讀的 name 屬性,其中包含關于函式的資訊,
多數情 況下,這個屬性中保存的就是一個函式識別符號,或者說是一個字串化的變數名,
即使函式沒有名稱, 也會如實顯示成空字串,
function AAA(){}
let BBB =function (){}
let CCC =()=>{}
console.log(AAA.name);
console.log(BBB.name);
console.log(CCC.name);
console.log((()=>{}).name);

(最后一行有東西的,空字符)
3.引數
ECMAScript 函式的引數跟大多數其他語言不同,
ECMAScript 函式既不關心傳入的引數個數,也不 關心這些引數的資料型別,
定義函式時要接收兩個引數,并不意味著呼叫時就傳兩個引數,
你可以傳一 個、三個,甚至一個也不傳,解釋器都不會報錯,(好家伙)
4.沒有多載
js沒有多載
(這可真是太有意思了,方法名是指標,引數不管數量,我想js自然是不會有多載的)
方法后定義覆寫先定義(記住了,要考的)
function add(num) {
return num + 100;
}
function add(num) {
return num + 200;
}
let result = add(100); // 300
顯然,定義兩個同名引數,后定義的會覆寫先定義的
5.arguments屬性
arguments 是一個類陣列物件,包含呼叫函式時傳入的所有引數,
function test(a,b,c,d,e){
console.log(arguments)
}
test(1,2,3,4);

5.1.arguments.callee
arguments 物件其實還有一個 callee 屬性,是一個指向 arguments 物件所在函式的 指標,
想不出什么好的例子,就用書中的原例吧:
(書中原例)
一個階乘遞回
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
隨后用arguments.callee代替factorial
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
這時候可能有人會問了,這有什么屌用.我剛開始也是這么想的,后來又看了兩遍,發現js開發者還是有點東西的
使用 arguments.callee 就可以讓函式邏輯與函式名解耦
我們接著看:
(重要的一個例子)
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
let trueFactorial = factorial;
factorial = function () {
return 0;
};
console.log(trueFactorial(5)); // 120
console.log(factorial(5)); // 0

這段就有意思了,
trueFactorial 變數被賦值為 factorial,所以console.log(trueFactorial(5));結果為120;
但是console.log(factorial(5)); 結果又為0;
trueFactorial 不受factorial方法重寫的影響
這一個例子就幫我們記住了三個知識點:
1.函式名真的是指標
2.使用 arguments.callee 就可以讓函式邏輯與函式名解耦
3.js有重寫,莫得多載
6.caller屬性
caller屬性參考的是呼叫當前函式的函式,或者如果是 在全域作用域中呼叫的則為 null,
function outer() {
inner();
}
function inner() {
console.log(arguments.callee.caller);
}
outer();

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544992.html
標籤:JavaScript
