[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类的理解和使用