一、具名函数和赋值式函数
1. 具名函数有预编译
fn() //输出:bye-bye
function fn() {
console.log('bye-bye');
}
2. 赋值式函数没有预编译
fn()
const fn = function() {
console.log('hello');
}
此时会报错:
匿名函数也属于赋值式函数,可以改写成箭头函数
箭头函数通常是匿名函数
const fn = (n) => {
console.log(n);
}
fn(5) //输出5
二、箭头函数介绍
箭头函数本质还是函数,但是与普通函数还是有区别的。
1. 箭头函数的简写:
- 形参有且只有一个的时候,省略小括号
const fn = n => {
console.log(n);
}
fn(5) //输出:5
- 有两个参数,不能简写
const fn2 = (n, m) => {
console.log(n + m);
}
fn(2, 3) //输出:5
- 当函数体只有一句代码且有返回值的时候 , 省略大括号和return
const fn3 = n => ++n;
const res = fn3(4);
console.log(res); //输出:5
1. 箭头函数没有arguments:
- 普通函数,可以通过arguments来实现重载;
- 箭头函数中,没有arguments,代替它功能是剩余参数rest(…)。
const fn = () => {
console.log(arguments[0], arguments[1]);
}
fn(1, 2 ,3) // 报错
- 使用展开运算符接受实参 …arr 得到的是一个真数组
const fn = (...rest) => {
console.log(rest);
}
fn(1, 2) //[1, 2]
2. 箭头函数没有原型对象:
- 普通函数,是有自己的原型对象的;
- 箭头函数,没有原型对象。
//普通函数
const fn = () => {
console.log('箭头函数');
}
console.log(fn.prototype); //undefined
//箭头函数
function fn2() {
console.log('普通函数');
}
console.log(fn2.prototype); //{constructor: ƒ}
3. 箭头函数不能作为构造函数:
- 普通函数,可以作为构造函数,通过new实例化出子函数;
- 箭头函数,不能作为构造函数,使用new会报错。
const fn3 = () => {
console.log('hello');
}
const a = new fn3(); //报错:fn3 is not a constructor
二、箭头函数的this指向
this一般是在函数里面出现的
出现位置 | this指向 |
---|---|
事件处理函数 | 事件源(即绑定事件的这个对象) |
对象的方法中 | 对象本身 |
普通函数中 | window |
严格模式下 | this没有指向 undefined |
箭头函数 | 没有自己的指向,追随父元素 |
- 箭头函数没有自己的this指向,父元素指向谁,箭头函数的this就指向谁。所以箭头函数可以维持住this的指向。
const fn = () => {
console.log(this); //this指向window
}
fn()
document.onclick = () => {
console.log(this); //this指向window
}
const obj = {
name: 'yy',
speak: function() {
console.log(this); //this指向 obj
},
say: () => {
console.log(this); //this指向 window
},
talk: function() {
console.log(this); //this指向 obj
setTimeout(() => {
console.log(this); //this指向 obj
console.log(this.name); // yy
}, 100)
}
}
console.log(obj.name); //yy
obj.talk(3)
document.onclick = function() {
console.log(this); //this指向 document
setTimeout(function() {
console.log(this); //this指向 window
})
setTimeout(() => {
console.log(this); //this指向 document
})
}
- 注意:箭头函数 this 不可变。call()、apply()、bind()、这些方法也 无法改变 箭头函数 this 的指向。
- 原因:箭头函数样意义上面来说没有this. 如果使用了this 那么就一定是外层this不会自动指向window对象。所以也就不能使用call/apply/bind来改变this指向
window.name = 'window';
var obj = {
name: 'obj',
}
var show_name = () => {
//这里 show_name 是箭头函数,他的this指window,并且不会变
console.log(this.name);
}
//用了 call 方法,但是 this 没变,所以打印了 window
show_name.call(obj); //window