首页 技术 正文
技术 2022年11月19日
0 收藏 898 点赞 4,450 浏览 3814 个字

其他章节请看:

es6 快速入门 系列

函数

函数是所有编程语言的重要组成部分,es6之前函数语法一直没什么变化,遗留了许多问题,javaScript开发者多年来不断抱怨,es6终于决定大力度更新函数特性,函数变得比以前更易于使用了。

试图解决的问题

默认参数

es5中模拟默认参数,通常这么实现:

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 才使用默认值

无命名参数

不定参数:函数的参数前加三个点(…)就表示这是一个不定参数,该参数是一个数组

用不定参数解决上面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'))

:不定参数有两条限制

  • 每个函数只能声明一个不定参数,且一定要放在所有参数后面
  • 不定参数不能用于对象字面量 setter 中
// 错误:不定参数不在末尾
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()

箭头函数也没有superargumentsnew.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

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

不定参数是将各自独立的参数整合成一个数组,展开运算符是将一个数组打散后作为独立的参数传入函数

判断函数是否用new调用

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]]函数,从而直接执行代码中的函数体

其他章节请看:

es6 快速入门 系列

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,484
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,899
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,732
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,485
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,125
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,286