函數(shù)
作為 JS 的一等公民,隨處可見它的身影。
我理解的它最主要作用就是用來提取重復代碼,但凡有 JS 代碼需要復制粘貼的時候,那么這時候就可以考慮使用函數(shù)封裝了。
當函數(shù)寫在對象中的時候,這時候它變了一個名字,稱之為 方法
。
function 聲明
在使用 function
關鍵字聲明函數(shù)時,需注意聲明提升問題,意思就是 function
聲明的函數(shù),不存在先后順序,任意位置都可以調(diào)用。
function test() {
console.log('前端路引');
}
test()
test
就是函數(shù)的名字,函數(shù)名的規(guī)則和變量聲明差不多,只要不是數(shù)字和特殊字符開頭,語法規(guī)則都是允許的,包括都可以使用中文定義函數(shù),雖然不建議這么使用!
function 測試() {
console.log('前端路引');
}
測試()
聲明提升
function 定義的函數(shù)會提升到作用域頂部,所以可以在函數(shù)定義之前調(diào)用,比如:
test()
const var1 = '前端路引 -- 1'
console.log(var1)
function test() {
console.log('前端路引 -- 2');
}
輸出:
前端路引 -- 2
前端路引 -- 1
包括寫在 if 判斷中的 function 都會提升到作用域頂部,比如:
test()
if (false) {
console.log('前端路引 -- 1');
function test() {
console.log('前端路引 --2');
}
}
輸出:
前端路引 -- 2
所以不建議在條件語句中去使用 function 聲明函數(shù)!
函數(shù)表達式
函數(shù)表達式就是使用一個變量來保存函數(shù),這種寫法有個好處是可以控制定義函數(shù)的邏輯。
聲明方式:
const test = function() {
console.log('前端路引');
}
test()
表達式聲明的函數(shù)只能在聲明之后調(diào)用,如果在聲明之前調(diào)用,代碼會報錯:
test()
const test = function() {
console.log('前端路引');
}
使用 var 聲明時會報錯 TypeError: test is not a function
:
test()
var test = function() {
console.log('前端路引');
}
在 if 中聲明的函數(shù)表達式,在外部無法調(diào)用:
if (false) {
const test = function() {
console.log('前端路引');
}
}
test()
箭頭函數(shù)
箭頭函數(shù)的聲明與函數(shù)表達式有些相似,都需要通過變量保存。
聲明方式:
const test1 = () => {
console.log('前端路引');
}
const test2 = (a, b) => a + b;
test1()
console.log(test2(1, 2))
箭頭函數(shù)和函數(shù)表達式的區(qū)別:
- 箭頭函數(shù)自身沒有
this
綁定,繼承外層作用域的 this
。
const test1 = function () {
console.log(this)
}
const test2 = () => {
console.log(this)
}
test1.bind({a: '123'})()
test2.bind({a: '123'})()
- 由于沒有
this
,所以也無法作為構造函數(shù)使用,不能使用 new
實例化。
const test1 = function () {
console.log('前端路引')
}
const test2 = () => {
console.log('前端路引')
}
new test1()
new test2()
- 箭頭函數(shù)也沒有
arguments
對象,所以無法通過 arguments
相關方法,比如 arguments.callee
獲取函數(shù)自身。
const test1 = function () {
console.log(arguments)
}
const test2 = () => {
console.log(arguments)
}
test1('前端路引')
test2('前端路引')
生成器函數(shù)
ES6 新增的聲明方式,常規(guī)的業(yè)務代碼一般很少使用(也可能是我的段位太低~~)。
function* test() {
yield 1;
yield 2;
}
const temp = test()
console.log(temp.next())
console.log(temp.next())
console.log(temp.next())
這種方式可以使用 yield
暫停函數(shù)執(zhí)行,多用于異步迭代場景。
看一個異步使用 yield
例子:
function* testAsync() {
const data = yield new Promise(resolve => {
setTimeout(() => resolve('Hello World'), 1000);
});
console.log(data);
}
async function run() {
const generator = testAsync();
const result = await generator.next().value;
generator.next(result);
}
run()
構造函數(shù) Function 聲明
雖然不建議使用這種聲明函數(shù),咱們學習了解一下還是沒問題的。
const test = new Function('a', 'b', 'return a + b');
console.log(test(1, 2))
問題:
1、通過字符串動態(tài)生成代碼,存在安全風險,容易出現(xiàn)代碼注入攻擊。
2、每次都會解析字符串,性能會比較低。
寫在最后
函數(shù)
作為 JS 語言中的一等公民,幾種聲明方式區(qū)別是面試中的???,經(jīng)常被問及 箭頭函數(shù)
與 function
有哪些區(qū)別。
函數(shù)
是基礎,也是函數(shù)式編程的核心,必須熟練掌握~~
轉自https://www.cnblogs.com/linx/p/18922032
該文章在 2025/6/11 9:45:29 編輯過