ES6新特性——函数的扩展
程序员文章站
2022-07-16 22:42:21
...
```handlebars
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/*
1.函数参数的默认值
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面
参数变量是默认声明的,不能用let和const再次声明
使用参数默认值时,函数不能有同名参数
参数默认值是惰性求值的
*/
//eg:
function log(x,y='world'){
console.log(x,y);
}
log('hello');//hello world
log('hello','china');//hello china
log('hello','');//hello
//eg:
function Point(x=0,y=0){
this.x=x;
this.y=y;
console.log(x,y)
}
const p=new Point();
//参数变量是默认声明的,不能用let和const再次声明
function foo(x=5){
let x=1; //x' has already been declared
const x=2; //x' has already been declared
console.log(x);
}
foo();
//参数默认值是惰性求值的,每次调用函数foo都会重新计算
let x=99;
function foo(p=x+1){
console.log(p);
};
foo();
//与解构赋值默认结合使用
//参数默认值可以与解构赋值的默认值,结合起来使用
function foo({x,y=5}){
console.log(x,y);
};
foo({});//undefined 5
foo({x:1});//1 5
foo({x:1,y:2});//1 2
foo();//property `x` of 'undefined' or 'null'
//赋值给{}代表提供函数参数的默认值
function foo({x,y=5}={}){
console.log(x,y);
};
foo();
//有{},原函数中没有赋值,就输出默认值,
//没有{},原函数中没有赋值,则报错
function fetch(url,{body='',method='GET',header={}}){
console.log(method);
}
fetch('ht',{});//GET
fetch('ht');//报错 undefined' or 'null'
//双重默认值可以取消报错
function fetch(url,{body='',method='GET',header={}}={}){
console.log(method);
}
fetch('ht');
//参数默认值的位置
function f(x=1,y){
console.log(x);
console.log(y);
}
f(2);//2 undefined;
f();
function foo(x=5,y=6){
console.log(x,y);
};
foo(undefined,null);//5 null
//函数的length属性:返回没有指定默认值的参数的个数
console.log(function (a) {}.length);//1
console.log(function(a=5){}.length);//0
console.log(function(a,b,c=1){}.length);//2
console.log(function(...args){}.length);
//如果设置了默认值的参数不是尾参数,那么length属性也不再计入后边的参数
console.log(function(q=0,b,c,d){}.length);
/*
作用域:
一旦设置了参数的默认值,函数进行声明初始化时,
参数会形成一个单独的作用域(context)。
等到初始化结束,这个作用域就会消失
这种语法行为,在不设置参数默认值时,是不会出现的
*/
var x=1;
function f(x,y=x){
console.log(y);
}
f(2);//2
/*
函数f调用时,参数y=x形成一个单独的作用域
这个作用域里面,变量x本身没有定义,
所以指向外层的全局变量x.
函数调用时,函数体内部的局部变量x影响不到默认值变量x
如果此时,全局变量x不存在,就会报错
*/
let x=1;
function f(y=x){
let x=2;
console.log(y);
}
f();//1
/*
rest参数
ES6引入rest参数(形式为 ...参数名),用于获取函数的多于参数,
这样就不需要使用arguments对象了
rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中
注意:
1.rest参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
2.函数的length属性,不包括rest参数
*/
//eg:
function add(...values){
let sum=0
for(var val of values){
sum+=val;
}
return sum;
}
//add();
let res=add(1,2,3);
console.log(res);
/*
arguments对象
arguments对象不是数组,而是一个类似数组的对象
如果要使用数组的方法,必须使用Arr.prototype.slice.call
先将其转为数组
*/
//arguments变量的写法
function sortNumbers(){
return Array.prototype.slice.call(arguments).sort();
}
let an=sortNumbers();
console.log(an);
//函数的length属性,不包括rest参数
console.log((function(a) {}).length);
console.log((function(...a){}).length);
console.log((function(a,b,e,...c){}).length);
/*
严格模式:
从ES5开始,函数内部可以设定严格模式
ES2016做了一点修改,规定只要函数参数使用了默认值、解构赋值、
或者扩展运算符,那么函数内部就不能显示设置为严格模式,否则会报错
*/
/*
name属性
函数的name属性,返回该函数的函数名
*/
function foo(){};
console.log(foo.name);
var f=function(){};
console.log(f.name);
//bind()方法:将函数绑定至某个对象
//bind返回的函数,name属性值会加上bound前缀
function foo(){};
console.log(foo.bind({}).name);
/*
箭头函数(=>)
*/
//基本用法
var f=v=>v;
//等同于
var f=function(v){
return v;
}
//如果箭头函数不需要参数或多个参数,就使用一个圆括号代表参数部分
var f=()=>5;
//等同于
var f=function(){return 5};
var sum=(num1,num2)=>num1+num2;
//等同于
var sum=function(num1,num2){return num1+num2;};
/*
由于大括号被解释为代码块,如果箭头函数直接返回一个对象,
必须在对象外加上括号,否则会报错
*/
let getTempItem=id=>({id:id,name:"Temp"});
//箭头函数可以与变量解构结合使用
const full=({first,last})=>first+''+last;
//等同于
function full(person){
return person.first+''+person.last;
}
//箭头函数使表达更简洁
const isEven=n=>n%2===0;
const square=n=>n*n;
//箭头函数的一个用处使简化回调函数
//正常函数写法
[1,2,3].map(function(x){
return x*x;
})
//箭头函数写法
[1,2,3].map(x=>x*x);
//正常函数的写法
var result=values.sort(function(a,b){
return a-b;
});
//箭头函数的写法
var result=values.sort((a,b)=>a-b);
//rest参数与箭头函数结合
const numbers=(...nums)=>nums;
numbers(1,2,3,4,5);
/*
使用箭头函数的注意点:
1.箭头函数体内的this指的是定义时所在的对象,
而不是使用时所在的对象,
在箭头函数里,this是固定的
2.不可以当作构造函数,也就是说,不可以使用new命令,
否则会抛出一个错误
3.不可以使用arguments对象,该对象在函数体内不存在。
如果要用,可以用rest参数替代
4.不可以使用yield命令,因此箭头函数不能作Generator函数
5.当函数体很复杂,有许多行,或者函数内部有大量的读写操作,
不单纯是为了计算值,也不应该使用箭头函数,而是要使用普通函数,
这样可以提高代码可读性
*/
//嵌套的箭头函数
function insert(value){
return {into:function(array){
return{after:function(afterValue){
array.splice(array.indexOf(afterValue)+1,0,value);
return array;
}}
}}
}
var a=insert(2).into([1,3]).after(1);
console.log(a);
//等价于
let insert=(value)=>({into:(array)=>({after:(afterValue)=>
{array.splice(array.indexOf(afterValue)+1,0,value);
return array;
}})})
var a=insert(2).into([1,3]).after(1);
console.log(a);
</script>
</body>
</html>
下一篇: .getClass 返回class名
推荐阅读
-
苹果iPad Air2与iPad Air有什么不同?盘点iPad Air2领先Air的15个新特性
-
Spring Boot2.3 新特性分层JAR的使用
-
ES6数组的扩展详解
-
JavaScript ES2019中的8个新特性详解
-
OpenCV中的新函数connectedComponentsWithStats使用(python和c++实例)
-
简述PHP7.4 新特性和废弃的功能
-
Java8新特性Lambda表达式的一些复杂用法总结
-
函数式接口 + Lamda表达式推导过程(Java8 新特性)
-
浅谈Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File Explorer
-
react16的新特性实例介绍