语法
javascript有基本的类函数,可以当做参数传递,最熟悉的setTimeout
setTimeout(function() {
console.log("setTimeout called!");
}, 1000);
上面这种函数是没有名字的,我们称之为匿名函数
es6中规定了不同的语法去定义匿名函数,这个叫做匿名函数,所以我们可以重新把以上代码写成
setTimeout(() => {
console.log("setTimeout called!")
}, 1000);
如果函数只有一个表达式,,就可以缩写成以下
setTimeout(() => console.log("setTimeout called!"), 1000);
参数
如果想要传递参数要怎么做呢?
以下这个代码要写成箭头函数
let add = function(a,b) {
return a + b;
};
可以写为
let add = (a,b) => a + b;
==在第一个例子中我们写了return a+b,但是在箭头函数中只写了a+b,那事因为在箭头函数中,如果只有一行,语句会自动返回,而不需要使用return关键字。==
this的指向
让我们假设我们有一个对象有一个叫做sayLater的函数
let obj = {
name: "asim",
sayLater: function() {
console.log(`${this.name}`);
}
};
obj.sayLater();
在sayLater函数中,这个this的指向是obj
所以console.log的值为asim
现在让我们来试一下用setTimeout函数输出的值是多少
let obj = {
name: "asim",
sayLater: function () {
setTimeout(function () {
console.log(`${this.name}`);
}, 1000);
}
};
obj.sayLater();
但是上面输出的值确实undefined
调用上下文
这个结果取决于这个函数的调用方式
在最基本的调用上obj.sayLater(),这个值是调用上下文,值为obj
拿在setTimeout的匿名函数中呢?this会指向什么呢?
setTimeout(function () {
console.log(`${this.name}`);
}, 1000);
他的答案就看情况了,在浏览器中,值是undefined或者是global对象,这个取决于是使用'use strict'或者非严格模式下,在node中他是一个超时对象
所以在setTimeout的例子中,this的值不会是obj,所以最后this.name返回的要么就是undefined或者是报错了。
这样不稳定的语法是个头疼的问题,也是javascript一直存在的问题,在es5中有很多方法解决这个问题,但是一般比较常用的方法就是,在调用上面声明个变量,一般叫做self或者vm,然后把这个用在函数中
let obj = {
name: "asim",
sayLater: function () {
let self = this; // Assign to self
console.log(self);
setTimeout(function () {
console.log(`${self.name}`); // Use self not this
}, 1000);
}
};
但是在es6中,我们有更好的方式解决这个问题,如果我们使用箭头函数,那箭头函数里面的this的值和外面的值是一样的
let obj = {
name: "asim",
sayLater: function () {
console.log(this); // `this` points to obj
setTimeout(() => {
console.log(this); // `this` points to obj
console.log(`${this.name}`); // `this` points to obj
}, 1000);
}
};
obj.sayLater();
可以尝试着跑以上的代码,就发现this输出来的都是obj
总结
新的箭头函数的语法,不止是语法上的简便,还解决了this的指向问题