箭头函数的学习笔记-ES6系列3

箭头函数的学习参考了以下几位大大们的博客~仅为自己的学习笔记。
http://es6.ruanyifeng.com/#docs/function
https://www.liaoxuefeng.com/wiki/1022910821149312/1031549578462080
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://www.jianshu.com/p/a416cb02e4a2

1. 什么是箭头函数

ES6允许使用箭头(=>)定义函数。如

var f = v => v;

这个箭头函数相当于

var f = function(v){
	return v;
}

我们可以这么理解,**箭头的左侧为函数的参数体,箭头右侧为函数的执行体。**一个箭头函数相当于一个匿名函数,如

(v => console.log(v))(2) //2

相当于

(function(v){
	console.log(v)
})(2)

1.1 参数何时加()

上面的例子是箭头函数的参数为一个时的写法。
(1)箭头函数无参数时,箭头的左侧应该由一个圆括号代表参数的部分。

var a = () => 5

相当于

var a = function(){
	return 5;
}

(2)箭头函数为多个参数时,也需要用圆括号将所有的参数括起来

var sum = (num1,num2) => num1+num2

相当于

var sum = function(num1.num2){
	return num1+num2;
}

1.2 函数体何时加{}和()

上面的例子是箭头函数的函数体为直接返回语句时(return时)。
(1)如果箭头函数的代码块部分多于一条语句,就需要使用大括号将其括起来,并且使用return语句返回。

var mulAndSum = (num1,num2) =>{
	let mul1 = num1 * 2
	let mul2 = num2 * 3
	return mul1+mul2;
}

(2)如果箭头函数直接返回一个对象,必须加上圆括号,否则会报错。

var returnObj = id => {id:id,name:"cjx"} //报错

应写成

var returnObj = id => ({id:id,name:"cjx"}) 
//试着打印出来看一下
console.log(returnObj(1))

相当于

var returnObj = function(id){
    return{
   	 id:id,
   	 name:"cjx"
    } 
}
//试着打印出来看一下
console.log(returnObj(1))

在这里插入图片描述

2. 嵌套的箭头函数

箭头函数内部还可以再使用箭头函数。

//ES5的多重嵌套如下
function insert(value) //(1)insert函数-返回对象
{
	return {
		into:function(array) //(2)into方法(函数)-返回对象
		{
			return{
				after:function(afterValue) //(3)after方法(函数)-返回数组
				{
					array.splice(array.indexOf(afterValue)+1, 0, value);
					return array;
				}
			}
		}
	}
}
console.log(insert(2).into([1, 3]).after(1)); //[1, 2, 3]

这个嵌套比较复杂 我们来缕一下逻辑。
(1)insert这个函数,返回了一个具有into方法的对象,
(2)into这个方法,返回了一个具有after方法的对象,
(3)after这个方法,执行了一段函数体,返回了一个数组。

我们来将以上代码转换成箭头函数,注意以下几点噢~
(1)箭头左边为参数,右边为函数体
(2)若返回是一个对象,必须用()括起来

let insert = value => ({into:(array)=>({after:(afterValue)=>{
	array.splice(array.indexOf(afterValue)+1, 0, value)
	return array
}})})
console.log(insert(2).into([1,3]).after(1))

是不是乍一眼 一脸懵 我们来试着分步写就很清楚啦~一步一步对应
(1)insert这个函数,返回了一个具有into方法的对象,即
let insert = (参数) => ({into:(2)})
(2)into这个方法,返回了一个具有after方法的对象
into:(参数)=>({after:(3)})
(3)after这个方法,执行了一段函数体,返回了一个数组。
after:(参数)=>{函数体}
这样再把三步合起来就是我们嵌套的箭头函数啦~

3. 箭头函数的注意点!

3.1 this

在ES6中,箭头函数的this不是调用的时候决定的,而是在定义的时候决定的,定义时所在的对象就是它的this。
即,在ES5当中,this是谁调用这个函数函数的的this就是谁。如

<body>
    

在这里插入图片描述
而在ES6中,this是函数定义时所处的对象(我认为是函数定义时所处的对象所指的this?),我们把上面的代码改成箭头函数来看看

<body>
    <button id = "btn1">btn1</button>
<script type="text/javascript">
    let btn1 = document.getElementById("btn1")
    btn1.onclick = ()=> console.log(this)  //函数定义时所处的对象。
</script>
</body>

在这里插入图片描述
来道网上的面试题来测试一下对箭头函数this的理解

window.color = "red";
let color = "green"; //思考如果这是var定义的时候结果又如何?
let obj = {
    color: "blue",
    getColor: () => {
        return this.color;
    }
};
let sayColor = () => {
    return this.color;
};
console.log(obj.getColor());
console.log(sayColor());

我们来思考一下这两个打印输出什么呢?
在这里插入图片描述
这是由于箭头函数的this在定义的时候就已经被绑定了。当在声明getColor和sayColor时,此时的this指向window。所以输出的为red。
若将这两个箭头函数都改成ES5时的函数声明呢?
在这里插入图片描述
getColor打印输出的就是blue了,这是由于这个非箭头函数是obj调用的,这个this就指向了obj。

若将let color = “green“ 改成 var color = ”green“的话。以上输出red的地方都变成了green。因为let 声明的全局变量不具有全局属性即不能用window.访问

window.color = "red";
var color = "green"; 
console.log("var:",color)
window.color1 = "blue";
let color1 = "yellow"
console.log("let:",color1)

在这里插入图片描述

3.2 this指向的固定化

箭头函数无法使用 call()或 apply()来改变其运行的作用域
我们再来看一道面试题~

let color = "red";
let obj = {
  color: "blue"
};
let sayColor = () => {
  return this.color;
};
sayColor.apply(obj);

这个的输出结果应该是什么呢?
在这里插入图片描述
输出undefined是由于:
(1)sayColor这个箭头函数在定义的时候this就确定为window了
(2)call()或apply()或bind()没有办法改变箭头函数的this,所以this还是window
(3)由于let声明的全局变量不属于window,而window对象的color属性未定义。所以输出undefined~

3.3 不可以当作构造函数

因为在构造函数中的 this 指向新创建的对象。而箭头函数的this无法指向新创建的对象。所以箭头函数不可以当作构造函数。不可以使用new命令,否则会抛出一个错误。

3.4 不可以使用arguments

在ES5中,我们可以使用arguments来获取参数列表,如下:

function func(){
    console.log(arguments)
}
func(1,2,3)

可打印出
箭头函数的学习笔记-ES6系列3_第1张图片
但在ES6的箭头函数中,这样是会报错的

var func1 = ()=>{
	console.log(arguments)
}
func1()

在这里插入图片描述
应当使用rest(剩余运算符)来代替arguments

var func1 = (...rest)=>{
    console.log(rest)
}
func1(1,2,3)

箭头函数的学习笔记-ES6系列3_第2张图片

3.5 不可以使用yield命令

箭头函数不能当做Generator函数,不能使用yield关键字。
(Generator还没看到,学完了再回来补这~)

3.6 箭头函数不适用场景

(1)由于this指向的原因,箭头函数不适用于定义对象的包含this的方法
(2)需要动态this的时候,也不应使用箭头函数。例如想为用this为按钮添加点击监听事件时。

你可能感兴趣的:(ES6,JavaScript)