this指向和例外的箭头函数

个人理解: this我们可以看成一个JavaScript为我们提供的"变量名", 它的指向问题就是它寻找自己变量的过程

1. this指向分析

根据红宝书上定义: this的指向取决于他运行时候的上下文,跟定义的时候没有关系.

  • 简单的例子来看一下this的指向问题:
javascript 复制代码
function foo() {
  console.log(this)
}
foo() // window

从上面可以看出this不是指向引用他的函数,只能它运行时候的上下文有关系.

2. this绑定的规则

<你不知道的JavaScript>定义: this的绑定和函数声明的位置没有任何关系, 之取决于函数的调用方式. 当一个函数被调用的时候,会创建一个活动记录(也称为执行上下文).

执行上下文(活动记录): 这个记录会包含函数在哪里被调用(调用栈),函数的调用方法,传入的参数等信息. this就是记录的其中的一个属性, 会在函数执行的过程中用到.

2.1默认绑定

默认绑定的情况下,全部指向Window

函数独自调用的情况就是默认绑定, this指向window

javascript 复制代码
var f = function () 
  console.log("foo函数:", this)
},
var obj = {
  a : a
  fn: fn
}
var b = obj.fn
b() // window

2.2隐式绑定

隐式绑定: 需要考虑是否被某个对象调用

javascript 复制代码
function foo() {
  console.log("foo函数:", this)
}
var obj = {
  foo: foo,
}
//情况一: 隐式绑定
obj.foo() //obj
//情况二: 默认绑定
var bar = obj.foo
bar() // window

当然还有一种例外的情况就是隐式丢失:

在情况二中bar是obj.foo的一个引用, 但是实际上, 它是独立调用,因此它应用了默认绑定.

2.3 显式绑定

显式绑定就是强制性绑定: 应用call(), apply(), bind()这三种函数对this的指向进行强制性绑定.

javascript 复制代码
function foo(a, b, c) {
  console.log("foo函数:", this)
  console.log("打印参数:", a, b, c)
}
//call绑定
foo.call("call", 10 , 20, 30)
//apply绑定
foo.apply("apply", [30, 20, 10])
//bind绑定
var bar = foo.bind("bind", 9, 8)
bar(7) 

2.4 new绑定

面向函数中"构造函数"是类的一种特殊方法,使用new初始化类会调用类中的构造函数.

javascript 复制代码
something = new MyClass(...)

new中this的绑定规则:

javascript 复制代码
function foo() {
  console.log("foo函数:", this)
}
new foo() //foo

在使用new来调用 foo( ) 时,我们会构建一个新的对象绑定到 foo( ) 调用this上. 我们称之为 new 绑定.

3. this绑定的优先级

需要注意的是: new和call/apply无法一起使用,因此不能通过new foo.call来直接进行测试

new绑定 > 显式绑定(bind > call = apply) > 隐式绑定 > 默认绑定

4. 箭头函数

箭头函数里面没有this,但是可以使用this, 像寻找变量一个向上寻找,从而决定this的指向.

箭头函数并不是使用function关键字定义的,而是使用操作符 => 定义的, 箭头函数不使用this的四种规则, 而是根据外层(函数或者全局)作用域开决定this

4.1箭头函数

箭头的基本使用:

javascript 复制代码
var foo3 = (name, age) => {
  console.log(name, age)
}

4.2箭头函数中的this

javascript 复制代码
//    this的查找规则
var obj = {
  name: "obj",
  foo: () => {
    var bar = () => {
      console.log("bar:", this)
    }
    return bar
  },
}
var fn = obj.foo()
fn()  //window
fn.apply("bbb") //Window

因为箭头函数中没有this, 所以在箭头函数中使用this, this需要一层层作用域向上寻找this指向.

必须注意的是:

在浏览器环境中 obj{ }不是一个作用域,所以找到window,

但是在 Node.js 中,没有像浏览器那样的全局 Window 对象。当执行 fn() 时,bar 函数内部的 this 同样没有被显式绑定,此时 Node.js 会将 this 设置为一个空对象 {},这是 Node.js 环境下的默认行为。

本文为圈友 zChao 总结的学习文章

原文链接:zhuanlan.zhihu.com/p/192317812...

相关推荐
骑着小黑马几秒前
从 Electron 到 Tauri 2:我用 3.5MB 做了个音乐播放器
前端·vue.js·typescript
进击的尘埃1 分钟前
前端大文件上传全方案:切片、秒传、断点续传与 Worker 并行 Hash 计算实践
javascript
aykon1 分钟前
DataSource详解以及优势
前端
Mintopia1 分钟前
戴了 30 天智能手环后,我才发现自己一直低估了“睡眠”
前端
leolee181 分钟前
react redux 简单使用
前端·react.js·redux
仰望星空的小猴子3 分钟前
常用的Hooks
前端
天才熊猫君3 分钟前
Vue Fragment 锚点机制
前端
米丘4 分钟前
Git 常用操作命令
前端
西梯卧客4 分钟前
[1-2] 数据类型检测 · typeof、instanceof、toString.call 等方式对比
javascript
星_离6 分钟前
SSE—实时信息推送
前端