目录
ES6以往文章
箭头函数的基本用法
箭头函数的用处
简化回调函数
rest参数与箭头函数结合
箭头函数使用注意点
this指向的问题
其它不存在的变量
不能使用call()、apply()、bind()方法改变this的指向
箭头函数不适用场合
定义对象时,对象方法内部包含this的使用
需要动态this时
嵌套的箭头函数
ES6以往文章
ES6标准---【一】【学习ES6看这一篇就够了!!】-CSDN博客
ES6标准---【二】【学习ES6看这一篇就够了!!】-CSDN博客
ES6标准---【三】【学习ES6看这一篇就够了!!!】-CSDN博客
ES6标准---【四】【学习ES6标准看这一篇就够了!!!】_es6 有arguments 吗-CSDN博客
箭头函数的基本用法
ES6允许使用“箭头”(=>)定义函数
语法结构:
(参数变量列表) => {操作)
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;
};
- 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用“return语句返回”
var sum = (num1,num2) => {return num1 + num2;}
- 如果箭头函数直接返回一个对象,必须在对象外面加上括号
// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });
- 如果箭头函数只有一行语句,且不需要返回值,可以用下面的写法,就不用写打括号了
let fn = () => void doesNotReturn();
- 箭头函数可以与变量解构结合使用
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
箭头函数的用处
简化回调函数
// 正常函数写法
[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,2,3,4,5]
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]
箭头函数使用注意点
- 函数体内的“this”对象,就是定义时所在的对象,而不是使用时所在的对象
- 不可以当作构造函数,也就是说,不可以使用“new”命令
- 不可以使用“arguments”对象,该对象在函数体内不存在,可以使用rest参数代替
- 不可使用“yield”命令,因为箭头函数不能用作Generator函数
特别注意:
“this”对象的指向是可变的,但是在“箭头函数”中是“固定的”
<body>
<script>
function foo() {
setTimeout(() => {
console.log('this.id是:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
</script>
</body>
效果:
如果是普通函数,执行时this对象会指向全局对象window,这时应该输出21
箭头函数导致this总是指向函数生效时所在的对象(即当前上下文环境,在这里是foo里的this.id),所以输出42
- 箭头函数可以让“setTimeout”里面的this绑定“定义时所在的作用域”
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
- Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数
- 前者的this绑定定义时所在作用域(Timer函数),后者的this绑定运行时的全局对象
- 因此3100ms后,timer.s1更新了三次,timer.s2一次都没有更新
- 箭头函数可以让“this”指向固定化,这中特性有利于封装回调函数(DOM事件的回调函数封装在一个对象里)
var handler = {
id: '123456',
init: function() {
document.addEventListener('click',
event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log('Handling ' + type + ' for ' + this.id);
}
};
this指向的问题
下面的代码中有几个“this”?
function foo() {
return () => {
return () => {
return () => {
console.log('id:', this.id);
};
};
};
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
上面的代码中, 只有一个this,就是函数foo的this
所以t1、t2、t3都输出同样的结果
因为所有的内层函数都是箭头函数,都没有自己的this,它们的this其实都是最外层foo函数的this
其它不存在的变量
除了“this”,下面三个变量:“arguments”、“super”、“new.target”在箭头函数中也是不存在的,都指向外层函数的对应变量
function foo() {
setTimeout(() => {
console.log('args:', arguments);
}, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
不能使用call()、apply()、bind()方法改变this的指向
(function() {
return [
(() => this.x).bind({ x: 'inner' })()
];
}).call({ x: 'outer' });
// ['outer']
箭头函数没有自己的this,所以bind方法无效,内部的this指向外部的this
箭头函数不适用场合
定义对象时,对象方法内部包含this的使用
<body>
<script>
var lives = 10;
var animal = {
lives: 9,
says: () => {
console.log("箭头函数的lives是:",this.lives);
}
}
var _animal = {
lives: 9,
says: function () {
console.log("箭头函数的lives是:",this.lives);
}
}
animal.says();
_animal.says();
</script>
</body>
效果:
对象不构成单独的作用域,因此animal的箭头函数会指向全局变量
需要动态this时
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});
上面代码运行时,点击按钮会报错
因为button的监听函数是一个箭头函数,导致里面的this就是全局对象
如果是普通函数,this就会动态指向被点击的按钮对象
嵌套的箭头函数
const plus1 = a => a + 1;
const mult2 = a => a * 2;
mult2(plus1(5))
// 12