iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >怎么理解并掌握JavaScript中的this关键字
  • 807
分享到

怎么理解并掌握JavaScript中的this关键字

2024-04-02 19:04:59 807人浏览 安东尼
摘要

这篇文章主要讲解了“怎么理解并掌握javascript中的this关键字”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解并掌握JavaScript中的

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

JavaScript 中的 this

JavaScript 引擎在查找 this 时不会通过原型链一层一层的查找,因为 this  完全是在函数调用时才可以确定的,让我们来看下面几种函数调用的形式。

1. Function Invocation Pattern

普通的函数调用,这是我们使用较多的一种, foo 是以单独的变量出现而不是属性。其中的 this 指向全局对象。

function foo() {   console.log(this) }  foo() // Window

函数作为对象的方法调用,会通过 obj.func 或者 obj[func] 的形式调用。其中的 this 指向调用它的对象。

const obj = {   name: 'lxfriday',   getName(){     console.log(this.name)   } }  obj.getName() // lxfriday

2. Constructor Pattern

通过 new Constructor() 的形式调用,其 this 会指向新生成的对象。

function Person(name){   this.name = name }  const person = new Person('lxfriday') console.log(person.name) // lxfriday

3. Apply Pattern

通过 foo.apply(thisObj) 或者 foo.call(thisObj) 的形式调用,其中的 this 指向 thisObj。如果  thisObj 是 null 或者 undefined ,其中的 this 会指向全局上下文 Window(在浏览器中)。

掌握以上的几种函数调用形式就基本可以覆盖开发中遇到的常见问题了,下面我翻译了一篇文章,帮助你更深入的理解 this。

如果你已经使用过一些 JavaScript 库,你一定会注意到一个特殊的关键字 this。

this 在 JavaScript 中很常见,但是有很多开发人员花了很多时间来完全理解 this 关键字的确切功能以及在代码中何处使用。

在这篇文章中,我将帮助您深入了解 this 其机制。

在深入了解之前,请确保已在系统上安装了 node 。然后,打开命令终端并运行 node 命令。

全局环境中的 this

this 的工作机制并不容易理解。为了理解 this 是如何工作的,我们将探索不同环境中的 this。首先我们从全局上下文开始。

在全局层面中,this 等同于全局对象,在 Node repl(交互式命令行) 环境中叫 global。

$ node > this === global true

但上述情况只出现在 Node repl 环境中,如果我们在 js 文件中跑相同的代码,我们将会得到不同的答案。

为了测试,我们创建一个 index.js 的文件,并添加下面的代码:

console.log(this === global);

然后通过 node 命令运行:

$ node index.js false

出现上面情况的原因是在 JS 文件中, this 指向 module.exports,并不是指向 global。

函数中的 this

Function Invocation Pattern

在函数中 this 的指向取决于函数的调用形式。所以,函数每次执行的时候,可能拥有不同的 this 指向。

在 index.js 文件中,编写一个非常简单的函数来检查 this 是否指向全局对象:

function fat() {   console.log(this === global) } fat()

如果我们在 Node repl 环境执行上面的代码,将会得到 true,但是如果添加 use strict 到首行,将会得到 false,因为这个时候  this 的值为 undefined。

为了进一步说明这一点,让我们创建一个定义超级英雄的真实姓名和英雄姓名的简单函数。

function Hero(heroName, realName) {   this.realName = realName;   this.heroName = heroName; } const superman= Hero("Superman", "Clark Kent"); console.log(superman);

请注意,这个函数不是在严格模式下执行的。代码在 node 中运行将不会出现我们预期的 Superman 和 Clark Kent ,我们将得到  undefined。

这背后的原因是由于该函数不是以严格模式编写的,所以 this 引用了全局对象。

如果我们在严格模式下运行这段代码,会因为 JavaScript 不允许给 undefined  增加属性而出现错误。这实际上是一件好事,因为它阻止我们创建全局变量。

最后,以大写形式编写函数的名称意味着我们需要使用 new 运算符将其作为构造函数来调用。将上面的代码片段的最后两行替换为:

const superman = new Hero("Superman", "Clark Kent"); console.log(superman);

再次运行 node index.js 命令,您现在将获得预期的输出。

构造函数中的 this

Constructor Pattern

JavaScript 没有任何特殊的构造函数。我们所能做的就是使用 new 运算符将函数调用转换为构造函数调用,如上一节所示。

进行构造函数调用时,将创建一个新对象并将其设置为函数的 this 参数。然后,从函数隐式返回该对象,除非我们有另一个要显式返回的对象。

在 hero 函数内部编写以下 return 语句:

return {   heroName: "Batman",   realName: "Bruce Wayne", };

如果现在运行 node 命令,我们将看到 return 语句将覆盖构造函数调用。

当 return 语句尝试返回不是对象的任何东西时,将隐式返回 this。

方法中的 this

Method Invocation Pattern

当将函数作为对象的方法调用时,this 指向该对象,然后将该对象称为该函数调用的接收者。

在下面代码中,有一个 dialogue 方法在 hero 对象内。通过 hero.dialogue() 形式调用时,dialogue 中的 this  就会指向 hero 本身。这里,hero 就是 dialogue 方法调用的接收者。

const hero = {   heroName: "Batman",   dialogue() {     console.log(`I am ${this.heroName}!`);   } }; hero.dialogue();

上面的代码非常简单,但是实际开发时有可能方法调用的接收者并不是原对象。看下面的代码:

const saying = hero.dialogue(); saying();

这里,我们把方法赋值给一个变量,然后执行这个变量指向的函数,你会发现 this 的值是 undefined。这是因为 dialogue  方法已经无法跟踪原来的接收者对象,函数现在指向的是全局对象。

当我们将一个方法作为回调传递给另一个方法时,通常会发生接收器的丢失。我们可以通过添加包装函数或使用 bind 方法将 this  绑定到特定对象来解决此问题。

call、apply

Apply Pattern

尽管函数的 this 值是隐式设置的,但我们也可以通过 call()和 apply() 显式地绑定 this。

让我们像这样重组前面的代码片段:

function dialogue () {   console.log (`I am ${this.heroName}`); } const hero = {   heroName: 'Batman', };

我们需要将hero 对象作为接收器与 dialogue 函数连接。为此,我们可以使用 call() 或 apply() 来实现连接:

dialogue.call(hero) // or dialogue.apply(hero)

需要注意的是,在非严格模式下,如果传递 null 或者 undefined 给 call 、 apply 作为上下文,将会导致 this  指向全局对象。

function dialogue() {   console.log('this', this) } const hero = {   heroName: 'Batman', } console.log(dialogue.call(null))

上述代码,在严格模式下输出 null,非严格模式下输出全局对象。

bind

当我们将一个方法作为回调传递给另一个函数时,始终存在丢失该方法的预期接收者的风险,导致将 this 参数设置为全局对象。

bind() 方法允许我们将 this 参数永久绑定到函数。因此,在下面的代码片段中,bind 将创建一个新 dialogue 函数并将其 this  值设置为 hero。

const hero = {   heroName: "Batman",   dialogue() {     console.log(`I am ${this.heroName}`);   } }; // 1s 后打印:I am Batman setTimeout(hero.dialogue.bind(hero), 1000);

注意:对于用 bind 绑定 this 之后新生成的函数,使用 call 或者 apply 方法无法更改这个新函数的 this。

箭头函数中的 this

箭头函数和普通函数有很大的不同,引用阮一峰 es6入门第六章中的介绍:

  • 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象;

  • 不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误;

  • 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替;

  • 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数;

上面四点中,第一点尤其值得注意。this 对象的指向是可变的,但是在箭头函数中,它是固定的,它只指向箭头函数定义时的外层 this,箭头函数没有自己的  this,所有绑定 this 的操作,如 call apply bind 等,对箭头函数中的 this 绑定都是无效的。

让们看下面的代码:

const batman = this; const bruce = () => {   console.log(this === batman); }; bruce();

在这里,我们将 this 的值存储在变量中,然后将该值与箭头函数内部的 this 值进行比较。node index.js 执行时将会输出  true。

那箭头函数中的 this 可以做哪些事情呢?

箭头函数可以帮助我们在回调中访问 this。看一下我在下面写的 counter 对象:

const counter = {   count: 0,   increase() {     setInterval(function() {       console.log(++this.count);     }, 1000);   } } counter.increase();

运行上面的代码,会打印 NaN。这是因为 this.count 没有指向 counter 对象。它实际上指向全局对象。

要使此计数器工作,可以用箭头函数重写,下面代码将会正常运行:

const counter = {   count: 0,   increase () {     setInterval (() => {       console.log (++this.count);     }, 1000);   }, }; counter.increase ();

类中的 this

类是所有 JavaScript 应用程序中最重要的部分之一。让我们看看类内部 this 的行为。

一个类通常包含一个 constructor,其中 this 将指向新创建的对象。

但是,在使用方法的情况下,如果该方法以普通函数的形式调用,则 this 也可以指向任何其他值。就像一个方法一样,类也可能无法跟踪接收者。

我们用类重写上面的 Hero 函数。此类将包含构造函数和 dialogue() 方法。最后,我们创建此类的实例并调用该 dialogue 方法。

class Hero {   constructor(heroName) {     this.heroName = heroName;   }   dialogue() {     console.log(`I am ${this.heroName}`)   } } const batman = new Hero("Batman"); batman.dialogue();

constructor 中的 this 指向新创建的类实例。batman.dialogue() 调用时,我们将 dialogue() 作为 batman  接收器的方法调用。

但是,如果我们存储对 dialogue() 方法的引用,然后将其作为函数调用,则我们将再次失去方法的接收者,而 this 现在指向  undefined。

为什么是指向 undefined 呢?这是因为 JavaScript 类内部隐式以严格模式运行。我们将 say()  作为一个函数调用而没有进行绑定。所以我们要手动的绑定。

const say = batman.dialogue.bind(batman); say();

当然,我们也可以在构造函数内部绑定:

class Hero {   constructor(heroName) {     this.heroName = heroName     thisthis.dialogue = this.dialogue.bind(this)   }   dialogue() {     console.log(`I am ${this.heroName}`)   } }

加餐:手写 call、apply、bind

call 和 apply 的模拟实现大同小异,注意 apply 的参数是一个数组,绑定 this 都采用的是对象调用方法的形式。

Function.prototype.call = function(thisObj) {   thisObjthisObj = thisObj || window   const funcName = Symbol('func')   const that = this // func   thisObj[funcName] = that   const result = thisObj[funcName](...arguments)   delete thisObj[funcName]   return result }  Function.prototype.apply = function(thisObj) {   thisObjthisObj = thisObj || window   const funcName = Symbol('func')   const that = this // func   const args = arguments[1] || []   thisObj[funcName] = that   const result = thisObj[funcName](...[thisObj, ...args])   delete thisObj[funcName]   return result }  Function.prototype.bind = function(thisObj) {   thisObjthisObj = thisObj || window   const that = this // func   const outerArgs = [...arguments].slice(1)   return function(...innerArgs) {     return that.apply(thisObj, outerArgs.concat(innerArgs))   } }

感谢各位的阅读,以上就是“怎么理解并掌握JavaScript中的this关键字”的内容了,经过本文的学习后,相信大家对怎么理解并掌握JavaScript中的this关键字这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么理解并掌握JavaScript中的this关键字

本文链接: https://www.lsjlt.com/news/85276.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么理解并掌握JavaScript中的this关键字
    这篇文章主要讲解了“怎么理解并掌握JavaScript中的this关键字”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解并掌握JavaScript中的...
    99+
    2024-04-02
  • 怎么理解并掌握JavaScript中的this
    这篇文章主要介绍“怎么理解并掌握JavaScript中的this”,在日常操作中,相信很多人在怎么理解并掌握JavaScript中的this问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望...
    99+
    2024-04-02
  • JavaScript中的this关键字用法详解
    目录this的绑定call与apply当方法失去主语的时候,this不再有?不可见的调用总结先举一个生活例子: 小明正在跑步,他看起来很开心 这里的小明是主语,如果没有这个主语,那么...
    99+
    2023-05-19
    JavaScript this关键字 JavaScript 关键字 JavaScript this
  • JavaScript的this关键字怎么引用
    这篇“JavaScript的this关键字怎么引用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看...
    99+
    2024-04-02
  • JavaScript中this关键字有什么用
    本篇内容主要讲解“JavaScript中this关键字有什么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中this关键字有什么用”吧!与...
    99+
    2024-04-02
  • JavaScript中的this关键字是什么及怎么用
    今天小编给大家分享一下JavaScript中的this关键字是什么及怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。例子...
    99+
    2023-06-26
  • js中的this关键字详解
    this是Javascript语言的一个关键字。 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。比如, 复制代码 代码如下:   function test(){  ...
    99+
    2022-11-15
    js this关键字
  • 怎么理解并掌握mysql中的information_schema
    本篇内容介绍了“怎么理解并掌握mysql中的information_schema”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细...
    99+
    2024-04-02
  • 怎么理解并掌握RAC
    这篇文章主要介绍“怎么理解并掌握RAC”,在日常操作中,相信很多人在怎么理解并掌握RAC问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解并掌握RAC”的疑惑有所帮助!接...
    99+
    2024-04-02
  • 怎么理解并掌握JavaScript中变量和作用域
    这篇文章主要讲解了“怎么理解并掌握JavaScript中变量和作用域”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解并掌握JavaScript中变量和作用域”吧!JavaScript的...
    99+
    2023-06-02
  • 怎么理解并掌握Redis
    本篇内容介绍了“怎么理解并掌握Redis”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Redis是一个开源的使用ANSI C语言编写、支持网...
    99+
    2023-06-02
  • 怎么理解并掌握MySQL
    本篇内容主要讲解“怎么理解并掌握MySQL”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么理解并掌握MySQL”吧!MySQL分为 server 层和存储引擎...
    99+
    2024-04-02
  • 怎么理解并掌握JVM
    本篇内容介绍了“怎么理解并掌握JVM”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、JVM的基本介绍JV...
    99+
    2024-04-02
  • 怎么理解并掌握mysql的表
    本篇内容介绍了“怎么理解并掌握mysql的表”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一.索引组织表如...
    99+
    2024-04-02
  • Java类中this关键字与static关键字的用法解析
    目录前言1:修饰属性,表示调用类中的成员变量。2:this修饰方法3:this表示当前对象的引用前言 今天给大家总结介绍一下Java类中this关键字和static关键字的用法。 t...
    99+
    2024-04-02
  • java中this关键字怎么使用
    这篇文章主要介绍了java中this关键字怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java中this关键字怎么使用文章都会有所收获,下面我们一起来看看吧。this 的使用:修饰属性和方法,也可以理...
    99+
    2023-06-26
  • 怎么理解并掌握Java的AVL树
    这篇文章主要介绍“怎么理解并掌握Java的AVL树”,在日常操作中,相信很多人在怎么理解并掌握Java的AVL树问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解并掌握J...
    99+
    2024-04-02
  • ASP中的关键字:您是否掌握了全部?
    ASP是一种流行的服务器端脚本语言,许多人都在使用它来构建动态网站和Web应用程序。在ASP中,关键字是非常重要的,因为它们定义了语言的基本构建块。在本文中,我们将深入探讨ASP中的关键字,以帮助您更好地理解这种语言的工作方式。 一、什么是...
    99+
    2023-08-26
    关键字 对象 ide
  • 怎么理解并掌握Python线程
    这篇文章主要讲解了“怎么理解并掌握Python线程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解并掌握Python线程”吧!1.自定义进程自定义进程类,继承Process类,重写ru...
    99+
    2023-06-25
  • Python 中关键字的学习笔记,你是否掌握?
    作为一名 Python 开发者,掌握 Python 的关键字是非常重要的。在本篇文章中,我们将深入探讨 Python 中的关键字,帮助你更好地理解和使用 Python 编程语言。 Python 中的关键字 Python 中有 35 个关键...
    99+
    2023-11-14
    文件 学习笔记 关键字
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作