#yyds干货盘点#ES6的this指向哪里

Posted 尼羲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#ES6的this指向哪里相关的知识,希望对你有一定的参考价值。

this小测试

下面的这段代码,this指向哪里?

var obj = 
a: function()
console.log(this);



var b = obj.a;
b();

结果是this指向window。

一般的,​this​指向函数运行(调用)时所在的执行环境【《javascript高级程序设计》4.2节执行环境及作用域】的(变量)对象(简单地,this​指向函数的调用者)

解析

var b = obj.a;    // ==>相当于
var b = function()
console.log(this);

函数调用时(​b();​)其所在的执行环境是全局环境,所以​this​指向全局变量对象​window​

ES6箭头函数

例1【阮一峰《ECMAScript 6 入门》-7.函数的扩展:箭头函数】

我将阮老师的例子代码修改了一下:
(普通函数)

function foo() 
console.log("id1:", this.id);
console.log("this1:", this);
setTimeout(function()
console.log("id2:", this.id);
console.log("this2:", this);
, 0);


var id = 21;

foo();

// Chrome
// id1: 21
// this1: window
// id2: 21
// this2: window

foo.call(id: 42);

// Chrome
// id1: 42
// this1: id: 42
// id2: 21
// this2: window

注意:超时调用(​​setTimeout​​​回调)的代码都是在全局作用域环境中执行的,因此(​​setTimeout​​回调)函数中​​this​​的值在非严格模式下指向​​window​​对象,在严格模式下是​​undefined​​​

例如

var obj = 
console.log(this);
setTimeout(function()
console.log(this);
, 0);


obj.a();

// Chrome
// a: f
// window

我们使用​​foo​​​函数的​​call​​​方法改变了​​foo​​​函数调用时函数体内​​this​​​的指向(​​id: 42​​​这个对象),但​​setTimeout​​​回调函数中的this依旧指向​​window​​对象(因为在全局环境中运行)。

接下来再将例1改写一下,将​​foo​​函数中的​​setTimeout​​回调函数改成箭头函数的形式:

例2
(箭头函数)

function foo() 
console.log("id1:", this.id);
console.log("this1:", this);
setTimeout(() =>
console.log("id2:", this.id);
console.log("this2:", this);
, 0);


var id = 21;

foo();

// Chrome
// id1: 21
// this1: window
// id2: 21
// this2: window

foo.call(id: 42);

// Chrome
// id1: 42
// this1: id: 42
// id2: 42
// this2: id: 42

​foo();​​​的输出结果没有变化,但​​foo.call(id: 42);​​的输出结果改变了。

到底发生了什么?

在这里直接给出结论:
箭头函数根本没有自己的​​this​​,导致内部的​​this​​指向了外层代码的​​this​​,这个指向在定义时就已经确定而不会在调用时指向其执行环境的(变量)对象

注意:因为箭头函数内部的​​this​​​是指向外层代码块的​​this​​(最近的​​this​​,例2中的foo函数)的,所以我们可以通过改变外层代码块的​​this​​的指向从而改变箭头函数中​​this​​的指向(例2中使用了​​foo​​函数的​​call​​方法)。

重新解释例2

因为箭头函数(​​setTimeout​​回调)没有自己的​​this​​,导致其内部的​​this​​引用了外层代码块的​​this​​,即​​foo​​函数的​​this​​,

(要注意:在定义阶段(调用函数前),​​foo​​​函数的​​this​​的值并不确定【《JavaScript高级程序设计》第三版5.5.4函数内部属性】,但箭头函数的​​this​​自定义阶段开始就指向​​foo​​函数的​​this​​了)

又因为使用​​call​​方法改变了​​foo​​函数运行(调用)时其函数体内​​this​​的指向(重新指向对象​​id: 42​​)从而使箭头函数中​​this​​的指向发生变化,最后输出例2所示结果。


以上是关于#yyds干货盘点#ES6的this指向哪里的主要内容,如果未能解决你的问题,请参考以下文章

《2w字大章 38道面试题》彻底理清JS中this指向问题 #yyds干货盘点#

#yyds干货盘点# 歌谣学前端之箭头函数2

#yyds干货盘点#ES6的扩展运算

#yyds干货盘点#ES6转换成ES5

#yyds干货盘点#重新解读一下ES6的Set

#yyds干货盘点#ECMAScript 6 - Symbol