7.函数的拓展
Posted mapengfei247
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.函数的拓展相关的知识,希望对你有一定的参考价值。
目录
函数的扩展
一.函数参数的默认值
1. 基本用法
ES6之前,不能直接为函数的参数设置默认值,只能在函数体内进行判断并给它赋默认值
//判断y是否存在,不存在则给它默认值 'world' function func(x,y) y ? y : 'world'; console.log(x + y);
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面**
- 注意:
- 函数的参数是默认声明的,不能使用 let 和 const 再次声明
- 参数默认值是惰性求值,只有当需要用到的时候,才会重新计算
function func(x,y = 'world') console.log(x + y); func('hello'); //helloworld func("hello",""); //hello
2.与解构赋值默认值结合使用
参数的默认值可以和解构赋值的默认值结合使用
思考:下面两种写法,有什么区别
function m1(x = 0,y = 0 = ) console.log(`[$x,$y]`) function m2(x,y = x:0,y:0) console.log(`[$x,$y]`)
- 第一种写法,函数参数的默认值是空对象,但是,设置了对象解构的默认值
- 第二种写法,设置了函数参数的默认值,但是没有设置对象解构的默认值
m1(); //[0,0] m2(); //[0,0] m1(x:3); //[3,0] m2(x:3); //[3,undefined] m1(x:3,y:5); //[3,5] m2(x:3,y;5); //[3,5] m1(); //[0,0] m2(); //[undefined,undefined]
3.参数默认值的位置
看如下示例
function func(x=0,y) console.log(`[$x,$y]`); func(); //[0,undefined] func(1); //[1,undefined] func(,3); //报错 func(undefined,3); //[0,3]
第二个示例
function func(x,y=0,z) console.log(`[$x,$y,$z]`) func(); //[undefined,0,undefined] func(1) //[1,0,undefined] func(1,,2) //报错 func(1,undefined,2) //[1,0,2]
总结如上两个示例,可以发现
- 如果非尾部的参数设置默认值,实际上这个参数是没办法省略的,至少得指定undefined,否则报错
- 当默认参数在最后的位置的时候,可不用指定
综上所述,拥有默认值的参数,一般放在参数列表的最后面
4.函数的length属性
指定了参数默认值的情况下,函数的length属性将只返回没有没有默认值的参数个数
(function func(x,y)).length; //2 (function func(x=0,y)).length; //1
5.默认参数的作用域
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域,等到初始化结束,作用域就会消失。这种语法行为,在不设置参数默认值的时候,是不会出现的
- 如下示例:
var x = 1; function foo(x,y=function()x=2;) var x = 3; y(); console.log(x); foo(); //3 console.log(x); //1
- 示例解析:在以上示例中,函数的参数形成了一个单独的作用域,在作用域内部,声明了一个变量x,声明了变量y,y的默认值为一个函数,这个函数内部的x指向同一个作用域的第一个参数x。在函数内部,又声明了一个x,该变量与参数内部的x不是同一个作用域,所以不是同一个变量,因此执行y后,函数内部的x变量和函数外部的x变量都没有发生变化
- 如果去掉函数内部的 var 声明,则函数内部的x变量和函数的第一个参数x是同一个变量,所以执行完y()方法之后,内部的x返回2
var x = 1; function foo(x,y=function()x=2;) x = 3; y(); console.log(x); foo(); //2 console.log(x); //1
6. 应用
- 可以将函数的某些参数的默认值设置为一个抛出异常的函数,当这些参数为undefined的时候,就会抛出异常
- 将参数的默认值设置为undefined,说明该参数可以被忽略
二.rest参数
ES6引入了rest参数,形式为(...变量名)。用户获取函数的多余参数,这样就不需要使用arguments对象了
- 注意:rest之后不能有其它参数,否则会报错
- rest参数就是一个数组,就函数多余的参数放入数组中
- 函数的length属性,不包含rest参数
function func(...numbers) console.log(numbers); func(1,2,3); //[1,2,3] console.log(func.length) //0
三.严格模式
从ES5开始,函数内部可以设置严格模式
function func() 'user strict'; //code...
ES6做了一点修改,规定只要函数参数使用了默认值,解构赋值,或者扩展运算符,那么函数内部就不能设定为严格模式,否则会报错
function func(x=10) 'use strict' //...报错
四.name属性
函数的name属性,返回该函数的函数名,这个属性很早就被浏览器支持,但是在ES6中,才将其写入标准
- 注意:
- 如果将一个匿名函数赋值给一个变量,ES5的name属性将会返回一个空串,在ES6中,会返回被赋值的变量名
- 如果将一个拥有名字的函数赋值给一个变量,不论是ES5还是ES6,其name属性会返回该函数原来的名字
const f = function bar() f.name; // bar
- Function 构造函数返回的实例,name属性值为 anonymous
(new Function).name //annoymous
五.箭头函数
1. 基本用法
- ES6允许使用“箭头”(=>)定义函数
var f = v => v;
//等同于
var f = function(v)
return v;
- 如果箭头函数不需要参数或者需要多个参数,就可以 使用一个圆括号代表参数部分
var f = () => 5
//等价于
var f = function()
return 5;
var f = (x,y) => x + y
//等价于
var f = function(x,y)
return x + y;
- 如果箭头函数直接返回一个对象,必须在对象外面加上圆括号,否则会报错
//报错
let getTempItem = id => id:id,name:'temp'
//不报错
let getTempItem = id => (id:id,name:'temp')
- 箭头函数可以和变量解构结合使用
let func = first,lasst => first + ',' + last
//等价于
function func(first,lasst)
return person.last + "," + person.last;
- 箭头函数可以简化回调函数
- 箭头函数可以和rest参数一起使用
2. 使用注意点
函数内的this对象,就是定义时所在的对象,而不是使用时所在的对象
不可以当做构造函数,也就是说不可以使用new进行实例化,否则报错
不可以使用arguments对象,但是可以使用rest参数代替
不可以使用yield命令,因此箭头函数不能用作Generator函数
箭头函数中的this,详细说明
- 箭头函数没有自己的this,所以箭头函数的this总是指向定义该箭头函数的那个对象
- 箭头函数让this的指向固定化
- 除了this,以下变量在箭头函数中也是不存在的,arguments,super,new.target
示例说明
var handle = id:'123456', init:function() document.addEventListener('click',event => this.doSomeThing(event.type),false) , doSomeThing:function(type) console.log('Handing' + type + 'for' + this.id) ;
示例解析:
- 上面代码中的init函数中使用了箭头函数,这导致箭头函数里面的this,永远指向handler对象,否则,使用this.doSomeThing调用的时候,就会报错
3. 不适用场合
- 由于箭头函数把this由动态变为静态,所以在以下场合,不应该使用箭头函数
- 定义对象的方法
- 需要动态this的时候
六.尾调用优化
1. 什么是尾调用
- 在某个函数的最后一步是调用另一个函数
function f(x)
return g(x);
- 没有按照上例中返回函数调用的,都不算尾调用
//非尾调用示例
function f(x)
let y = g(x);
return y;
function f(x)
return g(x) + 1;
function f(x)
g(x);
七.函数参数的尾逗号
- ES2017允许函数的最后一个参数可以有逗号,此前,这个都是不被允许的
总结
- ES6中,可以为函数添加默认值,默认值可以和解构赋值一起使用
- 函数默认值的位置最好放在函数参数的最后面,否则还是要在参数中使用undefined来使用默认参数,这使得默认参数没有什么意义
- 使用默认参数的函数,length返回只会返回没有默认值参数的个数
- 一旦设置了函数的默认参数,参数会形成一个单独的作用域
- ES6中新增了rest参数,rest参数可以接受所有未在函数参数列表中声明的参数,还可以代替arguments对象
- 使用了参数默认值,解构赋值和扩展运算符的函数,内部都不能指定严格模式,否则报错
- 函数的name属性可以返回函数名,将具名函数赋值给变量之后,name属性获取的还是函数的原始名
- 箭头函数可以简化函数的书写,但是得注意,箭头函数的this永远指向定义它的外城对象,箭头函数将动态的this变为了固定的
以上是关于7.函数的拓展的主要内容,如果未能解决你的问题,请参考以下文章