前言
1.ES5的函数形式
2.ES6的函数形式
3.ES5与ES6的this指向问题
一、ES5的普通函数
1.函数声明式
代码如下:
function fn (a, b, c) {
// ...
}
2.函数表达式形式
代码如下:
let fn = function (a, b, c) {
// ...
}
二、ES6的箭头函数
代码1:参数的三种形式
let fn = () => {
// ...
}
let fn = a => {
// ...
}
let fn = (a, b) => {
// ...
}
说明:这是ES6小括号写参数的三种形式,①如果没有参数,或者多于2个(包括2个)参数,小括号不可以省略 ②如果只有1个参数,小括号可以省略
代码2:花括号里面的奥妙,3种形式
// 返回表示式
let fn1 = (a, b) => a + b
// 返回对象形式
let fn2 = (a, b) => ({
a: a,
b: b
})
// 或
// 返回对象形式,一般用这种方法,容易理解
let fn2 = (a, b) => {
return {
a: a,
b: b
}
}
说明:
①如果函数返回的是表达式,可以省略花括号 。
②如果函数返回的是对象,就不能省略花括号 3.如果返回的是其他值,就还是不能省略
三、ES5与ES6的this指向问题
1.ES5普通函数的this指向
普通函数:根据调用我的人(谁调用我,我的this就指向谁)
代码1:
let obj1 = {
name: 'zhangsan',
say : function(){
console.log(this.name, this)
}
}
obj1.say()
结果:
说明:普通函数:根据调用我的人(谁调用我,我的this就指向谁)
代码2:
let bbb = {
bbb1: function(){
setTimeout(function(){
console.log(this)
}, 5000)
}
}
bbb.bbb1()// window
说明:
①5000mm后由setTimeout执行1次,所以指向window。没找到直接调用者,则this指的是 window (常见的window的属性和方法有: alert, location,document,parseInt,setTimeout,setInterval等)。
②在严格模式下,没有直接调用者的函数中的this是 undefined。
③使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象
2.ES6箭头函数的做法
箭头函数:根据所在的环境(我再哪个环境中,this就指向谁)
代码1:
let obj2 = {
name: 'zhangsan',
say : () => {
console.log(this.name, this)
}
}
// 对应是上层作用域window
obj2.say() //window
代码2:
let ccc = {
ccc1: function(){
setTimeout(() => {
console.log(this)// this指向ccc1:f
}, 500)
}
}
ccc.ccc1()
说明:箭头函数本身是没有作用域的,setTimeout也是没有的,所以500mm后,指向ccc1这个函数的作用域
代码3:一个ES6的案例,下面有几个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
说明:
①只有1个this,就是函数foo
的this
,所以t1
、t2
、t3
都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this
,它们的this
其实都是最外层foo
函数的this
。
②以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments
、super
、new.target
。
如代码:
function foo() {
setTimeout(() => {
console.log('args:', arguments);
}, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
③由于箭头函数没有自己的this
,所以当然也就不能用call()
、apply()
、bind()
这些方法去改变this
的指向。下面代码中,箭头函数没有自己的this
,所以bind
方法无效,内部的this
指向外部的this
。
如代码:
(function() {
return [
(() => this.x).bind({ x: 'inner' })()
];
}).call({ x: 'outer' });
// ['outer']
this是个常年以来令人苦恼的问题,有了ES6之后,造福了多少黎民百姓~谢谢ES6的发明者们