[TOC]
>[success] # 函數形參默認值
~~~
在'ES5'函數傳遞'默認值參數'時候通常大家都會像下面這么寫,如果'timeout'和'callback'不傳參數,
系統就會默認給'timeout'一個默認值'2000',給'callback'一個空的'function',但是這么寫有一個'缺陷',
如果'timeout'傳的值為'0'、'undefined'、'null',那么他的默認值都會為'2000',因為數字'0'、'undefined'、
'null'都為'false'
~~~
<br/>
>[success] ## 不嚴謹寫法
~~~
function makeRequest(url, timeout, callback) {
timeout = timeout || 2000
callback = callback || function () { }
}
// 有參數
makeRequest('www.baidu.com', 500, function(){console.log(123)})
// url = 'www.baidu.com'
// timeout = 500
// callback = function(){console.log(123)}
// 無參數
makeRequest()
// url = undefined
// timeout = 2000
// callback = function(){}
~~~
<br/>
>[success] ## ES5默認參數(嚴謹寫法)
~~~
function makeRequest(url, timeout, callback) {
// 這里typeof不可以這樣寫' typeof timeout !== null ' 因為null是空對象指針,他的類型是對象
timeout = (typeof timeout !== 'undefined' && typeof timeout !== 'object') ? timeout : 2000
callback = (typeof callback !== 'undefined' && typeof callback !== 'object' && typeof callback !== 'number') ? callback : function () { }
}
makeRequest('www.baidu.com', undefined, null)
timeout // 2000
callback // function(){}
~~~
<br/>
>[success] ## ES6默認參數寫法
~~~
function makeRequest(url, timeout = 2000, callback = function () { }) {
}
makeRequest('www.baidu.com', 0, undefined)
url // www.baidu.com
timeout // 0
callback // function(){}
// 如果不傳參數就是 undefined , undefined 時就會執行參數默認值, 但是null是空對象指針就會忽略
//默認值,打印出的值為null
makeRequest('www.baidu.com', null, undefined)
url // www.baidu.com
timeout // null
callback // function(){}
~~~
<br/>
>[success] ## 默認參數值對arguments的影響
### ES5非嚴格模式下
~~~
在ES5下'a'等于'arguments[0]','b'等于'arguments[1]',但是在'非嚴格模式下'修改了參數會
'同步更新'到'arguments'對象中,所以修改了'a'和'b'時,'arguments'對象會被重新賦值
~~~
~~~
function test(a, b) {
console.log(a === arguments[0])
console.log(b === arguments[1])
a = 1
b = 2
console.log(a === arguments[0])
console.log(b === arguments[1])
}
test(0, 0)
// true
// true
// true
// true
~~~
### ES5嚴格模式下
~~~
在'嚴格模式'下修改參數是不會導致'arguments'改變的。
~~~
~~~
function test(a, b) {
'use strict'
console.log(a === arguments[0])
console.log(b === arguments[1])
a = 1
b = 2
console.log(a === arguments[0])
console.log(b === arguments[1])
}
test(0, 0)
// true
// true
// false
// false
~~~
### ES6中的變化
~~~
在'ES6'的'默認值參數'的'方法中'無論你在'function'中,是否定義了嚴格模式(寫沒寫'use?strict'),
'ES6'都將以'ES5'的'嚴格模式'來看待
~~~
~~~
function test(a, b = 2) {
console.log(arguments.length)
console.log(a === arguments[0])
console.log(b === arguments[1])
a = 1
b = 2
console.log(a === arguments[0])
console.log(b === arguments[1])
}
test(0)
// 1
// true
// true
// false
// false
~~~
<br/>
>[success] ## 默認參數表達式( 默認參數小技巧 )
~~~
'默認參數表達式'更多的'傳默認值參數'的'技巧'。
~~~
<br/>
>[success] ### 技巧1( 函數當做默認參數 )
~~~
可以把'函數'當做'默認參數',然后在函數中計算后最終返回一個'計算結果'作為'參數',如下:
~~~
~~~
function c() {
return 5
}
function getValue(a, b = c()) {
return a + b
}
console.log(getValue(1, 2)) // 3
console.log(getValue(1)) // 6
或者
function getValue(value){ // 用來計算
return value + 5
}
function add(a, b = getValue(a)){
return a + b
}
console.log(add(1)) // 7
console.log(add(1,1)) // 2
~~~
<br/>
>[success] ### 技巧2( 參數1作為參數2的默認參數 )
~~~
把'參數1'作為'參數2'的'默認值參數',也可以作為'參數2'的方法的'參數'進行計算
~~~
~~~
function add(first, second = first) {
return first + second
}
console.log(add(1)) // 2
console.log(add(1, 1)) // 2
或者
function getValue(value){ // 用來計算
return value + 5
}
function add(a, b = getValue(a)){
return a + b
}
~~~
<br/>
### 注意
~~~
在'引用參數'作為'參數默認值'的時候,只可以'后面參數'引用'前面參數'當做默認值參數,
不可以'前面參數',引用'后面參數'作為'默認值參數',大白話就是'參數2'可以把'參數1',當成自己的
默認值參數,但是'參數1'不可以把'參數2'當做自己的'默認值參數',舉例:
~~~
~~~
function test(a = b, b){
return a + b
}
console.log(test(1,2)) // 3
console.log(test(undefined,1))
~~~
~~~
因為調用'test(undefined,1)'時候'a'使用'b'作為'參數'時候'b'還'未定義'
~~~
<br/>
>[success] ## 默認參數的臨時死區
~~~
簡單來說參數的執行方式和'let、const'一樣不存在'變量提升',如果'未定義初始化'就提前使用就會報錯。
~~~
### 正確寫法
~~~
function test(a, b = a){
return a + b
}
console.log(test(1,2)) // 3
// 相當于以下代碼
let a = 1
let b = 2
console.log(test(1)) // 2
// 相當于以下代碼
let a = 1
let b = a
~~~
### 錯誤寫法
~~~
function test(a = b, b){
return a + b
}
console.log(test(1,2)) // 3
// 相當于以下代碼
let a = 1
let b = 2
console.log(test(undefined,1)) // 報錯
// 相當于以下代碼
let a = b
let b = 1
~~~
- Javascript基礎篇
- Array數組
- 數組插入值
- filter()
- forEach()
- push()
- pop()
- unshift()
- shift()
- valueOf()
- 面向對象思想
- Javascript 面向對象編程(一):封裝
- Javascript面向對象編程(二):構造函數的繼承
- Javascript面向對象編程(三):非構造函數的繼承
- 解構
- 數組的解構賦值
- 對象的解構賦值
- 函數參數解構
- 字符串的解構賦值
- 數值和布爾值的解構賦值
- 圓括號問題
- 字符串.
- split()
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- match()
- replace()
- includes()
- 初識遞歸
- 渲染ul-li樹形結構
- 異步函數解決方案
- 1. callback回調函數
- 2. ES6 - Promise
- JavaScript高級程序設計(書)
- 在html中使用JavaScript
- script標簽的位置
- 延遲腳本
- 異步腳本
- <noscript>元素
- 基本概念
- 嚴格模式
- 變量詳解
- 數據類型
- typeof操作符
- undefined類型
- Null類型
- Boolean類型
- Number類型
- 深入了解ES6(書)
- var 、let 、 const
- 字符串與正則表達式
- 字符串
- 正則表達式
- 函數
- 函數形參默認值
- 使用不具名參數
- 函數構造器的增強能力
- 擴展運算符
- name屬性
- 明確函數的多重用途
- 塊級函數
- 箭頭函數
- 尾調用優化
- 擴展的對象功能
- 對象類別
- 對象字面量語法的擴展
- ES6對象新增方法
- 重復的對象屬性
- 自有屬性的枚舉順序
- 更強大的原型
- 解構:更方便的數據訪問
- 為什么要用解構?
- 對象解構
- 數組解構
- 混合解構
- 參數解構
- Symbol與Symbol屬性
- 創建Symbol
- Symbol的使用方法
- Symbol全局私有屬性
- Symbol與類型強制轉換
- Symbol屬性檢索
- Symbol的一些構造方法
- Set集合與Map集合
- Set集合
- Weak Set集合(弱引用Set集合)
- Map集合
- JS標準內置對象
- Object 構造函數及屬性
- Object 構造方法
- Symbol 內建對象類的函數及屬性
- Set 構造函數及屬性
- Weak Set 構造函數及屬性
- JS雜項
- 類數組對象
- Class類的理解和使用