欢迎访问WDPHP素材源码!今天是2024年05月04日 星期六,下午好!别打盹哦!
您好,游客 [ 马上登录 | 注册帐号 | 微信登录 | QQ登录]
当前位置:首页 > 教程 > 前端开发 > 

JavaScript执行上下文中的this怎么使用
栏目分类:前端开发    发布日期:2024-04-25    浏览次数:38次     收藏

这篇文章主要讲解了“JavaScript执行上下文中的this怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript执行上下文中的this怎么使用”吧!

前言

在对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但是 JavaScript 的作用域机制并不支持这一点,基于这个需求,JavaScript 有另外一套 this 机制。

this 是和执行上下文绑定的,也就是说每个执行上下文中都有一个 this。执行上下文主要分为三种——全局执行上下文、函数执行上下文和 eval 执行上下文,所以对应的 this 也只有这三种——全局执行上下文中的 this、函数中的 this 和 eval 中的 this。

全局执行上下文中的 this

全局执行上下文中的

this
是指向
window
对象的。这也是
this
和作用域链的 唯一交点,作用域链的最底端包含了
window
对象,全局执行上下文中的
this
也是指向
window
对象。

函数执行上下文中的 this

function foo() {
  console.log(this);
}
foo();

执行这段代码,打印出来的也是

window
对象,这说明在默认情况下调用一个函数,其执行上下文中的
this
也是指向
window
对象的。

通常情况下,有下面三种方式来设置函数执行上下文中的

this
值:

1. 通过函数的 call 方法设置

let bar = {
  myName: "极客邦",
  test1: 1,
};
function foo() {
  this.myName = "极客时间";
}
foo.call(bar);
console.log(bar);
console.log(myName);

执行这段代码,你就能发现

foo
函数内部的
this
已经指向了
bar
对象,因为通过打印
bar
对象,可以看出
bar
myName
属性已经由“极客邦”变为“极客时间”了,同时在全局执行上下文中打印
myName
,JavaScript 引擎提示该变量未定义。其实除了
call
方法,你还可以使用
bind
apply
方法来设置函数执行上下文中的
this

2. 通过对象调用方法设置

var myObj = {
  name: "极客时间",
  showThis: function () {
    console.log(this);
  },
};
myObj.showThis();

执行这段代码,你可以看到,最终输出的

this
值是指向
myObj
的。所以,你可以得出这样的结论:使用对象来调用其内部的一个方法,该方法的
this
是指向对象本身的。

接下来我们稍微改变下调用方式,把

showThis
赋给一个全局对象,然后再调用该对象,代码如下所示:
var myObj = {
  name: "极客时间",
  showThis: function () {
    this.name = "极客邦";
    console.log(this);
  },
};
var foo = myObj.showThis;
foo();

执行这段代码,你会发现

this
又指向了全局
window
对象。

结论:

在全局环境中调用一个函数,函数内部的

this
指向的是全局变量
window

通过一个对象来调用其内部的一个方法,该方法的执行上下文中的

this
指向对象本身。

3. 通过构造函数中设置

function CreateObj() {
  this.name = "极客时间";
}
var myObj = new CreateObj();

当执行

new CreateObj()
的时候,JavaScript 引擎做了如下四件事:

首先创建了一个空对象

tempObj

接着调用

CreateObj.call
方法,并将
tempObj
作为
call
方法的参数,这样当
CreateObj
的执行上下文创建时,它的
this
就指向了
tempObj
对象

然后执行

CreateObj
函数,此时的
CreateObj
函数执行上下文中的
this
指向了
tempObj
对象

最后返回

tempObj
对象
var tempObj = {};
CreateObj.call(tempObj);
return tempObj;

这样,就通过

new
关键字构建好了一个新对象,并且构造函数中的
this
其实就是新对象本身。

this 的设计缺陷以及应对方案

1. 嵌套函数中的 this 不会从外层函数中继承

var myObj = {
  name: "极客时间",
  showThis: function () {
    console.log(this);
    function bar() {
      console.log(this);
    }
    bar();
  },
};
myObj.showThis();

执行这段代码后,会发现函数

bar
中的
this
指向的是全局
window
对象,而函数
showThis
中的
this
指向的是
myObj
对象。

可以通过一个小技巧来解决这个问题,比如在

showThis
函数中声明一个变量
that
用来保存
this
,然后在
bar
函数中使用
that
。其实,这个方法的的本质是把
this
体系转换为了作用域的体系。

其实,你也可以使用 ES6 中的箭头函数来解决这个问题:

var myObj = {
  name: "极客时间",
  showThis: function () {
    console.log(this);
    var bar = () => {
      console.log(this);
    };
    bar();
  },
};
myObj.showThis();

这是因为 ES6 中的箭头函数并不会创建其自身的执行上下文,所以箭头函数中的

this
取决于它的外部函数。

2. 普通函数中的 this 默认指向全局对象 window

在实际工作中,我们并不希望函数执行上下文中的

this
默认指向全局对象,因为这样会打破数据的边界,造成一些误操作。如果要让函数执行上下文中的
this
指向某个对象,最好的方式是通过
call
方法来显示调用。

可以通过设置 JavaScript 的 严格模式 来解决(在第一行加上

"use strict";
)。在严格模式下,默认执行一个函数,其函数的执行上下文中的
this
值是
undefined
源码 模板 特效 素材 资源 教程 站长