其余章节请看:javascript
es6 快速入门 系列html
函数是全部编程语言的重要组成部分,es6以前函数语法一直没什么变化,遗留了许多问题,javaScript开发者多年来不断抱怨,es6终于决定大力度更新函数特性,函数变得比之前更易于使用了。java
es5中模拟默认参数,一般这么实现:es6
function demo1(v1, v2, v3){ v2 = v2 || 11 v3 = v3 || 22 }
更安全的作法是使用 typeof 检查编程
// 流行的javaScript库中均使用相似的模式 function demo2(v1, v2, v3){ v2 = (typeof v2 !== 'undefined') ? v2 : 11 v3 = (typeof v3 !== 'undefined') ? v3 : 22 }
不容易发现下面的函数 pick 能够接受任意数量的参数数组
// desc: 取出obj对象中的指定属性 function pick(obj){ const result = {} for(let i = 1, l = arguments.length; i < l; i++){ result[arguments[i]] = obj[arguments[i]] } return result; } const obj = {name: 'aaron', age:18, sex: 'man'} // 将obj对象中的name和sex属性取出 // { name: 'aaron', sex: 'man' } console.log(pick(obj, 'name', 'sex'))
建立函数的方式不太简洁,期待能少写一些字符来建立下面的函数安全
let getValue = function(v){ return v } let sum = function(v1, v2){ return v1 + v2 } let noop = function(){}
es6能在形参中指定默认值,就像这样:编程语言
function demo2(v1, v2 = 11, v3 = 22){ console.log(v2) console.log(v3) } // 11 22 demo2('v1') // 11 33 demo2('v1', undefined, 33) // null 22 demo2('v1', null)
注:全等于 undefined 才使用默认值函数
不定参数:函数的参数前加三个点(...)就表示这是一个不定参数,该参数是一个数组oop
用不定参数解决上面pick函数的问题:不容易发现pick()能够接受任意数量的参数
// desc: 取出obj对象中的指定属性 function pick(obj, ...keys){ const result = {} for(let i = 0, l = keys.length; i < l; i++){ result[keys[i]] = obj[keys[i]] } return result; } const obj = {name: 'aaron', age:18, sex: 'man'} // 将obj对象中的name和sex属性取出 // { name: 'aaron', sex: 'man' } console.log(pick(obj, 'name', 'sex'))
注:不定参数有两条限制
// 错误:不定参数不在末尾 function pick(obj, ...keys, last){} // 错误(之因此这么限制,是由于对象字面量 setter 的参数有且只能有一个) let obj = { set name(...v){ console.log('hello') } } obj.name = 1;
es6提供一种建立函数的新语法,即箭头函数,更加轻量,简介。
箭头函数的语法多变,根据实际场景由多种形式。全部变体都由函数参数、箭头和函数体组成
let getValue = v => v // 实际上至关于 let getValue = function(v){ return v }
let sum = (v1, v2) => v1 + v2; // 实际上至关于 let sum = function(v1, v2){ return v1 + v2 }
let noop = () => {} // 实际上至关于 let noop = function(){}
let getNumber = () => 100 // 实际上至关于 let getNumber = function(){ return 100 }
若是想经过箭头函数返回一个对象字面量,须要用将对象字面量包裹在括号中
let demo = id => ({id: id, age: 18}) // 实际上至关于 let demo = function(id){ return {id: id, age: 18} }
箭头函数没有 this,箭头函数的 this 由外围最近一层非箭头函数决定
// 箭头函数的this,就是函数init中的this let obj = { id: 11, init: function(){ document.addEventListener('click', evt => { console.log(this.id) // 11 }) } } obj.init()
箭头函数也没有super、arguments、new.target,这些值与 this 同样,都有外围最近一层非箭头函数决定
不能经过 new 关键字调用,由于头函数没有[[Constructor]],因此不能被用做构造函数
const Sum = (v1, v2) => v1 + v2 new Sum() // 报错
默认参数能够传非原始值
function getValue(){ console.log('执行') return 11 } /* 经过函数执行来获得参数的默认值 */ function demo2(v1, v2 = getValue()){ console.log(v2) } demo2('v1') // 执行 11 demo2('v1', 12)
默认参数的临时死区
function getValue(v){ return v } function add(first=getValue(second), second = 100){ const result = first + second console.log(result) return result } add(1, 2) // 3 {1} add(undefined, 2) // 报错 {2} add(10) // 110 {3}
默认参数也存在讲let和const时介绍的临时死区TDZ
// {1}:表示调用add(1, 2)时的js代码 let first = 1 let second = 1; // {2}: 表示调用add(undefined, 2)时的js代码 let first = getValue(second) // second还在临时死区中 let second = 2
Function构造函数,咱们一般用它来构造新的函数,这种构造函数接受字符串的形式,分别是函数的参数和函数体
const add = new Function('v1', 'v2', 'return v1 + v2') console.log(add(10, 20)) // 30
es6中Function构造函数也支持默认参数和不定参数
// 默认参数 const add = new Function('v1', 'v2 = 20', 'return v1 + v2') console.log(add(10)) // 30 // 不定参数 const add = new Function('...keys', 'return keys[0] + keys[1]') console.log(add(10, 20)) // 30
展开运算符与函数中的不定参数很类似
console.log(Math.max(1, 3, 2)); // 3 // 展开运算符 console.log(Math.max(...[1, 3, 2])) // 3 console.log(Math.max(...[1, 3, 2], 4)) // 4
不定参数是将各自独立的参数整合成一个数组,展开运算符是将一个数组打散后做为独立的参数传入函数
es6中引入 new.target 来解决判断函数是否经过new关键字调用的问题
// es5中限制函数必须经过new调用的实现以下: function People(){ if(this instanceof People){ console.log('created') }else{ throw new Error('必须经过 new 调用') } } const p1 = new People() // created People.call(p1) // created(有效)
当调用函数的[[Constructor]]方法时,new.target被赋值为new操做符的目标,若是调用[[Call]]方法,则new.target的值为undefined
function People(){ if(new.target === People){ console.log('created') }else{ throw new Error('必须经过 new 调用') } } const p1 = new People() // created People.call(p1) // Error: 必须经过 new 调用
注:js函数有两个内部方法:[[Call]]和[[Construct]],当经过new关键字调用函数时,执行[[Construct]]函数,它负责建立称做实例的新对象;若是不经过new关键字调用函数,则执行[[Call]]函数,从而直接执行代码中的函数体
其余章节请看: