【05】ES6:函數的擴展

一、函數參數的默認值

ES6 允許為函數的參數設置默認值,即直接寫在參數定義的后面。

1、基本用法

默認值的生效條件

不傳參數,或者明確的傳遞 undefined 作為參數,只有這兩種情況下,默認值才會生效。

注意:null 就是 null,不會使用默認值。

// ES6 之前的默認值實現方式
const log = (x, y) => {// typeof類型檢測:返回表示當前數據類型的字符串if (typeof y === 'undefined') {y = 'world'}console.log(x, y)
}log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
// ES6 默認值實現方式
function log(x, y = 'World') {console.log(x, y)
}log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

默認值的一些規則

參數變量是默認聲明的,所以不能用let或const再次聲明。

function foo(x = 5) {let x = 1 // errorconst x = 2 // error
}

使用參數默認值時,函數不能有同名參數。

// 不報錯
function foo(x, x, y) {// ...
}// 報錯 SyntaxError: Duplicate parameter name not allowed in this context
function foo(x, x, y = 1) {// ...
}

參數默認值是惰性求值的。參數默認值不是傳值的,而是每次都重新計算默認值表達式的值。

let x = 99
function foo(p = x + 1) {console.log(p)
}foo() // 100x = 100
foo() // 101

2、與解構賦值默認值結合使用

函數參數默認值 可以與 解構賦值的默認值,結合起來使用。通過給函數參數設置默認值,可以避免在沒有提供參數時出現錯誤。

// 只使用對象的解構賦值默認值
function foo({ x, y = 5 }) {console.log(x, y)
}foo({}) // undefined 5
foo({ x: 1 }) // 1 5
foo({ x: 1, y: 2 }) // 1 2
// 函數 foo()調用時沒提供參數,變量 x 和 y 就不會生成,從而報錯
foo() // TypeError: Cannot read property 'x' of undefined// -------------------------------------------// 使用對象的解構賦值默認值 + 函數參數的默認值
function foo({ x, y = 5 } = {}) {console.log(x, y)
}foo() // undefined 5
// 只使用對象的解構賦值默認值
function fetch(url, { body = '', method = 'GET', headers = {} }) {console.log(method)
}fetch('http://example.com', {}) // 'GET'
fetch('http://example.com') // 報錯// --------------------------------------------------// 使用對象的解構賦值默認值 + 函數參數的默認值
function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {console.log(method)
}fetch('http://example.com') // 'GET'

注意,函數參數的默認值生效以后,參數解構賦值依然會進行。

// 參數默認值 { a: 'hello' } 生效;進行解構賦值,從而觸發參數變量 b 的默認值生效。
function f({ a, b = 'world' } = { a: 'hello' }) {console.log(b)
}f() // world// 解構賦值的默認值只在屬性值為 undefined 時才會生效
function f({ a, b = 'world' } = { b: 'hello' }) {console.log(b)
}f() // hello

3、參數默認值的位置

通常情況下,定義了默認值的參數,應該是函數的尾參數。因為這樣比較容易看出來,到底省略了哪些參數。如果非尾部的參數設置默認值,實際上這個參數是沒法省略的。

// 例一
function f(x = 1, y) {return [x, y]
}f() // [1, undefined]
f(2) // [2, undefined]
f(, 1) // 報錯
f(undefined, 1) // [1, 1]// 例二
function f(x, y = 5, z) {return [x, y, z]
}f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報錯
f(1, undefined, 2) // [1, 5, 2]

上面代碼中,有默認值的參數都不是尾參數。這時,無法只省略該參數,而不省略它后面的參數,除非顯式輸入 undefined。

如果傳入 undefined,將觸發該參數等于默認值,null 則沒有這個效果。

function foo(x = 5, y = 6) {console.log(x, y)
}foo(undefined, null) // 5 null

4、函數的 length 屬性

函數的 length 屬性,等于該函數預期傳入的參數個數。

當函數指定默認值后,length 屬性將失真。將返回沒有指定默認值的參數個數,如果設置了默認值的參數不是尾參數,那么 length 屬性也不再計入后面的參數了。

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2(function(...args) {}).length // 0(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1

5、應用

利用參數默認值,可以指定某一個參數不得省略,如果省略就拋出一個錯誤。

function throwIfMissing() {throw new Error('Missing parameter')
}function foo(mustBeProvided = throwIfMissing()) {return mustBeProvided
}foo() // Error: Missing parameter

上面代碼的 foo 函數,如果調用的時候沒有參數,就會調用默認值 throwIfMissing 函數,從而拋出一個錯誤。

從上面代碼還可以看到,參數 mustBeProvided 的默認值等于 throwIfMissing 函數的運行結果(注意函數名 throwIfMissing 之后有一對圓括號),這表明參數的默認值不是在定義時執行,而是在運行時執行。如果參數已經賦值,默認值中的函數就不會運行。

另外,可以將參數默認值設為 undefined,表明這個參數是可以省略的。

function foo(optional = undefined) { ··· }

二、reset 參數(…不定參數)

ES6 引入 rest 參數(形式為…變量名),用于獲取函數的多余參數,這樣就不需要使用 arguments 對象了。rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。

function add(...values) {let sum = 0for (var val of values) {sum += val}return sum
}add(2, 5, 3) // 10
// arguments 變量的寫法
function sortNumbers() {// arguments 為類數組對象,需先使用 Array.from 轉換為數組return Array.from(arguments).sort()
}// rest 參數的寫法 (reset 參數為真正的數組)
const sortNumbers = (...numbers) => numbers.sort()

注意,rest 參數之后不能再有其他參數(即只能是最后一個參數),否則會報錯。

// 報錯
function f(a, ...b, c) {// ...
}

函數的 length 屬性,不包括 rest 參數。

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

三、箭頭函數

ES6 規定了可以使用 “箭頭” => 來定義一個函數,語法更加簡潔。它沒有自己的 this、arguments、super 或 new.target,箭頭函數表達式更適用于那些本來需要匿名函數的地方,但它不能用作構造函數。

1、基本使用

普通函數

function 函數名() {}const 變量名 = function () {}

箭頭函數

(參數) => {函數體}const 變量名 = () => {}
// 基本語法
const add = (x, y) => {return x + y
}// 有且只有一個參數,()可以省略
const add = x => {return x + 1
}// 有且只有一條語句,且為 returen 語句,{} 和 return 可以省略
const add = (x, y) => x + y// return 為對象時,對象外需要加 ()
const add = (x, y) => {return {value: x + y}
}
const add = (x, y) => ({ value: x + y })

2、函數 this 指向

es5 中的 this 指向

函數 this 的取值,是在函數執行的過程中確定的,不是在函數定義時確定的。

(1) 作為普通函數被調用,this 指向 window

(2) 作為對象方法被調用時,this 指向當前對象

(3) 在構造函數中(es5, es6的class方法),this 指向通過構造函數創建的實例對象

(5) 定時器中函數的 this 指向 window,定時器中函數相當于普通函數被調用(setTimeout | setInterval)

es6 中箭頭函數的 this 指向

箭頭函數中的 this 是在定義的時候綁定的,this 取上級作用域的 this,箭頭函數本身不會決定 this 的值。

call、 apply 、 bind

fn.call(this, …params) 和 fn.apply(this, [params]) 都是用來改變函數的this指向
區別是傳參不同,call()接受的是列表,apply()接受的是數組

fn.bind(this, params) 方法也是用來改變函數this指向,但是不會立即執行,而是返回一個新函數

3、不適用箭頭函數的場景

作為構造函數

因為箭頭函數沒有 this,而構造函數的核心就是 this。

需要 this 指向調用對象的時候

因為箭頭函數沒有 this,所以如果箭頭函數中出現了 this,那么這個 this 就是外層的!

給事件綁定方法時,比如說通過 addEventListener 給某個事件綁定方法,如果使用箭頭函數,此時 this,會指向父級的this window

在定義某個對象的方法時,不可以使用箭頭函數

在 vue 的 methods 中的方法,也不可以使用箭頭函數,會使 this 指向的不是當前的vm實例,發生錯誤

需要使用 arguments 的時候

箭頭函數沒有 arguments。(這個問題有替代解決方案:不定參數)

沒有原型

由于箭頭函數不能用作構造函數,它們也沒有自己的原型。因此,不能使用 prototype 屬性來添加新方法。

不可以使用 yield 命令,因此箭頭函數不能用作 Generator 函數

四、函數參數的尾逗號

ES2017 允許函數的最后一個參數有尾逗號(trailing comma)。

此前,函數定義和調用時,都不允許最后一個參數后面出現逗號。

function clownsEverywhere(param1,param2
) { /* ... */ }clownsEverywhere('foo','bar'
)

上面代碼中,如果在 param2 或 bar 后面加一個逗號,就會報錯。

如果像上面這樣,將參數寫成多行(即每個參數占據一行),以后修改代碼的時候,想為函數 clownsEverywhere 添加第三個參數,或者調整參數的次序,就勢必要在原來最后一個參數后面添加一個逗號。這對于版本管理系統來說,就會顯示添加逗號的那一行也發生了變動。這看上去有點冗余,因此新的語法允許定義和調用時,尾部直接有一個逗號。

function clownsEverywhere(param1,param2,
) { /* ... */ }clownsEverywhere('foo','bar',
)

這樣的規定也使得,函數參數與數組和對象的尾逗號規則,保持一致了。

五、catch 命令的參數省略

JavaScript 語言的 try…catch 結構,以前明確要求 catch 命令后面必須跟參數,接受 try 代碼塊拋出的錯誤對象。

try {// ...
} catch (err) {// 處理錯誤
}

上面代碼中,catch命令后面帶有參數err。

很多時候,catch代碼塊可能用不到這個參數。但是,為了保證語法正確,還是必須寫。ES2019 做出了改變,允許catch語句省略參數。

try {// ...
} catch {// ...
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167327.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167327.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167327.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

react的開發中關于圖片的知識

React是一個流行的JavaScript庫,用于構建用戶界面。在React開發中,圖片是一個非常重要的元素,可以用于美化界面和展示內容。本篇博客將詳細講解React中關于圖片的知識。 1. React中使用圖片 在React中使用圖片非常簡單,只需要使…

【Web題】狼追兔問題

💝💝💝歡迎來到我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內容和知識,也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

解決Resolving Android Dependencies問題

無論是谷歌的Admob,還是Unity的Level play, 在windows(win10, win11)下,都出現了resolving android dependencies 報錯并且卡住的問題,如圖: 主要錯誤,是找不到這個gradlew.bat文件。 在指定位置…

什么是單元測試?

什么是單元測試 單元測試是軟件開發中的一種測試方法,旨在驗證各個軟件組件或模塊的功能正確性。在敏捷開發環境中,單元測試尤為重要,因為它有助于確保代碼的質量和穩定性。下面是一些關于單元測試的關鍵點: 定義:單元…

力扣每日一題-統計和小于目標的下標對數目-2023.11.24

力扣每日一題:統計和小于目標的下標對數目 開篇 今天這道力扣打卡題寫得我好狼狽,一開始思路有點問題,后面就是對自己的代碼到處縫縫補補,最后蒙混過關。只能分享一下大佬的代碼,然后我幫大家分享代碼的思路。 題目鏈…

大模型能否生成搜索引擎的未來?

文|郝 鑫 編|劉雨琦 ChatGPT火爆之前,水面下,也有中國公司也在朝著智能助手的方向努力。夸克便是其中之一。在GPT風靡科技圈后,國內就開始陸續冒出一些大模型廠商。對當時夸克而言,做大模型毋庸置疑&am…

django(千鋒教育)

創建一個django項目 官網下載python最新版本 配置到環境變量中 打開intlij編輯器 創建django項目 安裝django:pip install django 創建django項目: django-admin startproject django01 創建djangoAPP:python manage.py startapp App 啟動&#xff1a…

設置定時自動請求測試_自動定時循環發送http_post請求---postman工作筆記001

其實就是創建接口文件夾的時候,有個monitor collection 用來監聽接口執行情況,這里就可以設置 可以看到多久執行一次對吧,這里可以設置每幾分鐘執行一次,一共執行多少次等等 但是這里要說明一下,如果需要使用monitor功能,必須需要登錄, 所以如果這里點擊monitor collection…

媒體增加日活量的有效策略

隨著數字媒體的蓬勃發展,提高日活量成為媒體平臺追求的重要目標之一。日活量的增加不僅意味著更廣泛的影響力,還能為媒體平臺帶來更多的商業機會。以下是一些有效的策略,可幫助媒體提高日活量: admaoyan貓眼聚合 內容優質化&#…

**QT與目標板聯合調試_斷點仿真**

原文地址: https://blog.csdn.net/u012851408/article/details/86715626

仙女麻麻看過來~這是不是你們在找的外套?

分享女兒的秋冬穿搭 時尚與美觀兼具的毛毛外套 洋氣百搭不挑人穿 誰穿對都好看系列 經典寬松版型 不臃腫對身材包容性很強 小編墻裂推薦哦!!

NFT Insider115:The Sandbox開設元宇宙Diorama快閃店,?YGG Web3 游戲峰會已開幕

引言:NFT Insider由NFT收藏組織WHALE Members、BeepCrypto聯合出品,濃縮每周NFT新聞,為大家帶來關于NFT最全面、最新鮮、最有價值的訊息。每期周報將從NFT市場數據,藝術新聞類,游戲新聞類,虛擬世界類&#…

RevCol:可逆的柱狀神經網絡

文章目錄 摘要1、簡介2、方法2.1、Multi-LeVEl ReVERsible Unit2.2、可逆列架構2.2.1、MACRo設計2.2.2、MicRo 設計 2.3、中間監督 3、實驗部分3.1、圖像分類3.2、目標檢測3.3、語義分割3.4、與SOTA基礎模型的系統級比較3.5、更多分析實驗3.5.1、可逆列架構的性能提升3.5.2、可…

貴金屬交易指南:如何在市場中獲利?

貴金屬市場一直以來都是投資者追逐利潤的熱門選擇,然而,貴金屬市場波動較大,在市場中獲利并非易事。想要成功,需要理解市場動態和采取適當的策略。萬洲金業將為您提供一些實用的貴金屬交易指南,幫助您在市場中獲利。 …

PostgreSQL create or replace view和重建視圖 有什么區別?

一、 replace vs 重建 遇到開發提了個問題,create or replace view和重建視圖(dropcreate)有什么區別,查詢資料整理了一下。 1. create or replace 當存在同名視圖時,嘗試將其替換新視圖語句必須與現有視圖查詢具有相…

LeetCode算法題解(動態規劃,背包問題)|LeetCode1049. 最后一塊石頭的重量 II、LeetCode494. 目標和

一、LeetCode1049. 最后一塊石頭的重量 II 題目鏈接:1049. 最后一塊石頭的重量 II 題目描述: 有一堆石頭,用整數數組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。 每一回合,從中選出任意兩塊石頭,然后將…

springboot2.1升級到2.7 actuator丟失部分metrics端點

項目場景: 項目需要升級springboot從2.1升級至2.7 問題描述 發現之前的metrics后面的jvm相關的端口丟了 原因分析: 找到這樣一篇博文https://blog.csdn.net/CL_YD/article/details/120309094,這篇博文意思是對的,但是寫的不太好…

Java基于springoot開發的企業招聘求職網站

演示視頻: https://www.bilibili.com/video/BV1xw411n7Tu/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 技術:springootmysqlvuejsbootstrappoi制作word模板 主要功能:求職者可以注冊發布簡歷,選擇簡…

案例018:基于微信小程序的實習記錄系統

文末獲取源碼 開發語言:Java 框架:SSM JDK版本:JDK1.8 數據庫:mysql 5.7 開發軟件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序開發軟件:HBuilder X 小程序…

【python入門篇】函數(6)

這一節將詳細介紹Python中函數的用法,包括函數的定義、調用、參數、返回值、作用域等。 函數的概述: Python函數是一種封裝了特定任務的可重用代碼塊。通過將程序分解為更小、更具體的任務,函數提供了一種有效的方式來組織和管理代碼&#xf…