JS ES6匿名函数和箭头函数
1、匿名函数
匿名函数即没有名字的函数,在使用时:可以当做变量的值、当做参数值、可以自调用;ES6中的匿名函数同ES5,但是在ES6中,匿名函数包含了箭头函数。
例:
//将匿名函数当做变量的值:
let show = function(a,b){
console.log(a,b);//10,20
}
show(10,20);
function show4(){
let m = function(){
console.log('key');//key
}
m();
}
show4();
let stu = {
id:1,
name:'zhang',
shown:function(){
console.log(this.name);
}
}
stu.shown();//zhang
//将匿名函数当做参数值:
function show5(k){
//回调函数
k();
}
show5(function(){
//调用了匿名函数
console.log('a');//a
});
//匿名函数自调用:
(function(){
console.log('b'); //b
})();
(function(a,b){
console.log(a + b);//300
})(100,200);
2、箭头函数
(1)箭头函数的写法: 去掉函数名,去掉function,在() 与{}之间加=>:
()=>{}
(name)=>{}
(name,age)=>{}
箭头函数的使用方法大多与匿名函数相同——可以当做变量的值、当做参数值、可以自调用,关于箭头函数的几种写法如下:
//箭头函数当做变量值:
let show1 = () => {
console.log('show1');//show1
};
show1();
let show2 = (name) => {
console.log(name);//zhang
};
show2('zhang');
let show3 = (name, age) => {
console.log(name, age);//wang 20
};
show3('wang', 20);
function show4() {
let test = (name, age) => {
console.log(name, age);//wang 20
};
test('wang', 20);
}
show4();
//箭头函数当做对象成员的值:
let stu = {
name: 'zhou',
show: () => {
console.log('abc');//abc
}
}
stu.show();
//箭头函数当做参数值:
function test1(a, b, c) {
let r = a + b;
c(r);
}
// function test2(z){
// console.log(z);//30
// }
// test1(10,20,function(z){
// console.log(z);
// });
test1(10, 20, (z) => {
console.log(z);//30
});
//箭头函数自调用:
(()=> {
console.log('b');//b
})();
((a, b)=> {
console.log(a + b);//300
})(100, 200);
(2)箭头函数的变形:
-
当箭头函数函数体只有一条语句时,包围函数的{}可以去掉;
-
当箭头函数体中只有一条返回语句时,可省去{},并省去return;
-
当有仅只有1个形参时,包围形参的()可省;
例:
//当箭头函数函数体只有一条语句时,可以省略{}
let show1 = ()=>console.log('a');
show1();//a
//当箭头函数只有一条返回语句时,可以去掉{}和return
let show2 = ()=>100;
console.log(show2());//100
let show3 = ()=>'zhnag';
console.log(show3());//zhang
//当带参数的箭头函数只有一条返回语句时,可以去掉{}和return
let show4 = (m,n)=>m + n;
console.log(show4(10,100));//110
//当箭头函数有且仅有一个形参时,保卫形参的()可以省略
let show5 = key=>key;
console.log(show5(200));//200
(3)箭头函数中的this:
-
箭头函数的外层函数中的this就是箭头函数中的this,当外层函数中的this发生改变时,箭头函数中的this也会发生改变
-
如果没有外部普通函数(箭头函数之外的函数),则this就是window
例1:箭头函数和call()比较:
//1
let obj = {
x:200
}
let stu = {
x:100,
m1:function(){
let y = ()=>{
console.log('y',this.x);
}
y();
}
}
//this指stu
stu.m1();
//this指obj
stu.ma.call(obj);
stu.m1();
//2
var adder = {
base: 1,
add: function (a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function isFun(a) {
var f = v => v + this.base;
var b = {
base: 2
};
return f.call(b, a);
}
};
//add中 var f = v => v + this.base的this指的是add的this即adder
console.log(adder.add(1));//2
//未执行f.call(b, a)时,addThruCall中var f = v => v + this.base的this是
//addThruCall的this即adder,执行了f.call(b, a)后,由于箭头函数外层函数并未改变
//所以,此时的this依然是adder;如果这里是addThruCall.call,那么this可能会改变
例2:当箭头函数没有外部函数时,this指向window,不能被改变
var animal = "人";
let obj = {
animal: '狗',
}
let getAnimal = () => this.animal;
//这里this指的是window
console.log(getAnimal());//人
//当箭头函数没有外部函数时,this指向window,不能被改变
(4)箭头函数与普通函数比较:
- 箭头函数内部没有arguments,普通函数可以使用arguments获取所有实参
- 箭头函数内部的this是指向定义时的对象而不是使用时的对象,普通函数内部的this是谁调用就指向谁
- 箭头函数不能new,普通函数可以new
- 箭头函数没有function,使用=>来定义;普通函数使用function来定义
例:
let a = () => {
console.log(arguments);
//arguments is not defined
}
a()
let b = function(){
console.log(arguments);
//类数组{1,2,3,4,5}
}
b(1,2,3,4,5)
想要在箭头函数内获取所有输入的实参值,可以使用可变参数来接收实参值,接收到的实参会组成一个数组:
例:
let a = (...arg) => {
console.log(arg);
//[1,2,3,4,5]
}
a(1,2,3,4,5)
- 箭头函数和普通函数都可以参与解构,使用时,可以对函数返回值和实参进行解构
例:函数返回值解构:
//箭头函数返回值解构
let calculator = (a,b)=>{
return {
add: a + b,
sub: a - b,
mul: a / b,
divided: a * b
}
}
let {add,sub,mul,divided} = calculator(10,20);
console.log(add,sub,mul,divided);
//自调用箭头函数返回值解构
let {selfadd,selfsub} = ((a,b)=>{return {selfadd: a++,selfsub: b--} } )(1,2);
console.log(selfadd,aelfsub);
//普通函数返回值解构
function fun(a,b) {
return {
add1: a++,
sub1: b--
}
}
let {add1,sub1} = fun(10,20);
console.log(add1,sub1);
//自调用普通函数返回值解构
let {add2,sub2} = addSub = function(a,b) {
return {
add2: a++,
sub2: b--
}
}
console.log(add2,sub2);
例2函数参数解构——实参解构给形参,实参是源,形参是目标
//普通函数参数解构
function add({x,y} = {x:10,y:20}){
cosole.log(x,y);//undefined undefined
}
add({}); //{x,y} = {}
function add2({x = 10,y = 20}){
cosole.log(x,y);
}
add2({}); //{x = 10,y = 20} = {}
//箭头函数参数解构
let add3 = ({x,y} = {x:10,y:20}) => {cosole.log(x,y);};
add({});
let add4 = (({x,y} = {x:10,y:20}) => {cosole.log(x,y);})({});
(5)箭头函数的使用场景:
- 对象中的方法尽量不要使用箭头函数
- 构造函数中的方法可以使用构造函数
- 当有外部函数时,要保证内部函数的this指向,可以将内部函数写成箭头函数
- 当需要维护上下文的this时,最好使用箭头函数