Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] 第33天 说说你对this的理解 #120

Open
haizhilin2013 opened this issue May 18, 2019 · 20 comments
Open

[js] 第33天 说说你对this的理解 #120

haizhilin2013 opened this issue May 18, 2019 · 20 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

第33天 说说你对this的理解

@haizhilin2013 haizhilin2013 added the js JavaScript label May 18, 2019
@github-linong
Copy link

js 中有两个重要概念:作用域和原型链

我个人感觉
作用域对应函数式开发,闭包是主要工具
原型链对应对象式开发,this 是主要工具,把一些操作封装在一个工具包上,然后用 this 来调用

@tzjoke
Copy link

tzjoke commented May 28, 2019

this在不同场景下指向也不同,比如有可能指向new出来的对象,可能指向全局对象,通过apply/call/bind还可以指向传入的第一个参数,等等。。。

@myprelude
Copy link

this

指的是当前运行环境的上下文。当然这个this是会发生改变的 如 bind call apply

@AnsonZnl
Copy link
Contributor

AnsonZnl commented Jul 4, 2019

基本上可以归为四类,
全局this 是window
函数this 是调用者
构造函数的this 是new 之后的新对象
call 和 apply bind的this第一个参数

@jiamianmao
Copy link

不严谨说法,谁调用这个函数,this就指向谁。
通常来说,this指向该函数的执行上下文。
arrow function 指向它上一级的执行上下文。

@Konata9
Copy link

Konata9 commented Aug 31, 2019

JavaScript 中的 this 用一句话来概括,就是在执行时确定的。从现象上来看,就是谁调用了某个方法,那么这个方法中的 this 指向谁。

下面是最常见的例子:

const obj = {
  sayThis: function() {
    console.log(this);
  }
};

obj.sayThis(); // obj
const globalSay = obj.sayThis;
globalSay(); // window 浏览器中的 global 对象

谁调用了某个方法,那么这个方法中的 this 指向谁

这个“谁”我们可以通过 . 操作符来判断。比如 obj.sayThis(),这里就是 obj 调用了 sayThis 方法,所以 this 指向 obj。而后一个 globalSay() 是直接调用的,在 JavaScript 中会把这个方法绑在全局(window)上,所以本质就是 window.globalSay(),自然这里的 this 就指向了 window

JavaScript 给我们提供了 apply/call/bind 三种方法来改变 this 的指向。在 ES6 的语法中还提供了箭头函语法,让我们在代码书写时就能确定 this 的指向(编译时绑定)。唯一需要注意的就是要避开箭头函数带来的坑。

把上面的例子改为箭头函数,结果完全不同。

const obj = {
  sayThis: () => {
    console.log(this);
  }
};

obj.sayThis(); // window 因为 JavaScript 没有块作用域,所以在定义 sayThis 的时候,里面的 this 就绑到 window 上去了
const globalSay = obj.sayThis;
globalSay(); // window 浏览器中的 global 对象

参考文章:
前端基础进阶(五):全方位解读 this
深入解读 React 组件中的 "this" - 知乎

@abueavan
Copy link

abueavan commented Nov 13, 2019

https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch2.md
判定 this
按照优先顺序来总结一下从函数调用的调用点来判定 this 的规则了。按照这个顺序来问问题,然后在第一个规则适用的地方停下。
1、函数是通过 new 被调用的吗(new 绑定)?如果是,this 就是新构建的对象。
var bar = new foo()
2、函数是通过 call 或 apply(或bind) 被调用?如果是,this 就是那个被明确指定的对象。
var bar = foo.call( obj2 )
3、函数是通过环境对象(也称为拥有者或容器对象)被调用的吗(隐含绑定)?如果是,this 就是那个环境对象。
var bar = obj1.foo()
4、否则,使用默认的 this(默认绑定):如果在 strict mode 下,就是 undefined,否则是 global 对象。
var bar = foo()
如果你传递 null 或 undefined 作为 call、apply 或 bind 的 this 绑定参数,那么这些值会被忽略掉,使用默认的this。“更安全”的做法是:为了 this 而传递一个特殊创建好的对象,创建完全为空的对象的最简单方法就是 Object.create(null)(见第五章)。Object.create(null) 和 {} 很相似,但是没有指向 Object.prototype 的委托,所以它比 {} “空得更彻底”。
与这四种绑定规则不同,ES6 的箭头方法使用词法作用域来决定 this 绑定,这意味着它们采用封闭他们的函数调用作为 this 绑定。它们实质上是 ES6 之前的 self = this 代码的语法替代品。

@blueRoach
Copy link

  • 全局this指向window
  • 函数执行时,就指向执行时的函数
  • 构造函数的指向new它的对象
  • 箭头函数不会改变函数的指向
  • 可以通过apply call bind方法来改变函数的指向,指向就是第一次参数

@Alex-Li2018
Copy link

  1. 在普通函数中,this指向window

  2. 在对象中this指向这个对象,但是有特殊情况
    特殊例子
    在其被调用时才确定this指向

  3. 定时器,延时器里的this指向是window

  4. 构造函数中的this指向是new实例化之后的实例

  5. apply,call,bind会改变this指向
    apply改变this指向,第二个参数是数组
    call改变this指向,第二参数是一个一个参数
    bind改变this指向,但是不会立即执行,返回一个新的函数

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

@CoderLeiShuo
Copy link

一般情况

函数中的this永远指向函数的调用者(在代码执行时才能确定),谁最终调用这个函数,this就指向谁

  • 在全局环境中,this指向window(如果开启严格模式,this将指向undefined)
  • 如果函数是通过new绑定的(构造函数),那么this就指向new出来的对象
  • 如果函数是通过对象调用的,那么this就指向这个对象(但要小心this绑定丢失,尤其要注意将函数作为值向函数中传入赋值时发生隐式丢失)
  • 如果函数是通过callapplybind进行绑定,那么this就指向被绑定的对象

箭头函数

箭头函数中的this例外,它指向定义时所在的位置。或者可以说箭头函数的this继承自外层作用域,只要确定了外层作用域的this,就知道箭头函数中的this指向谁了。

@bozaigao
Copy link

bozaigao commented Oct 5, 2020

如果函数是独立调用的话this就指向的是全局对象,如果是对象调用那么就指向的是这个对象,并且通过call/apply可以改变this指向,对比箭头函数中的this指向的是父级作用于中的this,并且通过call/apply无法改变this指向。

@smile-2008
Copy link

基本上可以归为四类,
全局this 是window
函数this 是调用者
构造函数的this 是new 之后的新对象
call 和 apply bind的this第一个参数

@tardis103
Copy link

this的指向不是在编写的时候确定的,是在执行的时候确定的。分为四类:

  1. 默认绑定:非严格模式下this指向全局对象,严格模式下指向undefined
  2. 隐式绑定:如果函数被一个对象调用,this指向该对象
  3. 显示绑定:使用 call apply bind 改变this指向,指向第一个参数
  4. new绑定:构造函数的this 指向new之后的新对象

箭头函数中没有this绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数所包含,this指向最近一层非箭头函数的this,否则是undefined

@lzlstrongest
Copy link

全局this指向window
函数执行时,就指向执行时的函数
构造函数的指向new它的对象
箭头函数不会改变函数的指向
可以通过apply call bind方法来改变函数的指向,指向就是第一次参数

@HNHED
Copy link

HNHED commented Sep 4, 2021

`## 什么是this
this指的是运行环境的上下文

this的指向

首先判断函数类型

  • 箭头函数
    -包裹箭头函数的第一个普通函数中的this
  • 普通函数
    -函数如何被调用
    • new的方式:this被固化在实例上
    • 除了new的方式
      -foo():this为window
      -obj.foo():this为obj
  • call、bind、apply
    this是第一个参数`

@zxcdsaqwe123
Copy link

谁调用指向谁

@xiaoqiangz
Copy link

this是指当前运行环境的上下文,可以通过call、apply、bind来改变当前上下文。 箭头函数的this指向父级函数的this。
new关键字指向的当前实例, 全局下使用fn() this指向window,如果函数是通过对象来调用的obj.fn() this则指向obj。

@mohaixiao
Copy link

我的答案

this是一个关键字,被自动定义在所有函数的作用域中。
一般来说,this的指向是根据调用的上下文来决定的。
this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将 API 设计得更加简洁并且易于复用。
this的指向又分为5种,分别是默认绑定,隐式绑定,显示绑定,new绑定,还有箭头函数绑定。

@CoderLeiShuo
Copy link

CoderLeiShuo commented Jul 8, 2022 via email

@never123450
Copy link

在JavaScript中,关键字 this 代表当前执行代码的上下文对象。它通常在函数内部使用,用于引用当前正在执行函数的对象。

this 的值是在函数调用时动态确定的,取决于函数的调用方式。以下是一些常见的情况:

  1. 全局上下文中的 this :在全局作用域中, this 指向全局对象(在浏览器中是 window 对象)。

  2. 函数中的 this :在函数中, this 的值取决于函数的调用方式。如果函数作为对象的方法调用, this 指向该对象。如果函数作为普通函数调用, this 指向全局对象(非严格模式下)或 undefined (严格模式下)。

  3. 构造函数中的 this :当使用 new 关键字调用构造函数创建对象时, this 指向新创建的对象。

  4. 事件处理函数中的 this :在事件处理函数中, this 通常指向触发事件的元素。

需要注意的是, this 的值是在运行时确定的,而不是在编写代码时确定的。因此,同一个函数在不同的上下文中可能具有不同的 this 值。

理解 this 的关键是了解函数的调用方式和上下文。通过正确理解和使用 this ,可以访问和操作适当的对象,实现更灵活和可重用的代码。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests