ES5普通函数与ES6箭头函数的说明【拓展:它们的this指向问题】

前言

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,就是函数foothis,所以t1t2t3都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this,它们的this其实都是最外层foo函数的this

②以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:argumentssupernew.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的发明者们

发布了62 篇原创文章 · 获赞 11 · 访问量 8622

猜你喜欢

转载自blog.csdn.net/qq_38588845/article/details/103424680
今日推荐