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...

相关推荐
嘿siri7 分钟前
html全局遮罩,通过websocket来实现实时发布公告
前端·vue.js·websocket·前端框架·vue·html
Lorcian9 分钟前
web前端1--基础
前端·python·html5·visual studio code
十三月❀27 分钟前
当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线
javascript·vue.js·elementui
牧云流33 分钟前
Vue3数据响应式原理
javascript·vue.js·ecmascript
不爱学英文的码字机器40 分钟前
[JavaScript] 深入理解流程控制结构
开发语言·前端·javascript
violin-wang1 小时前
XML映射文件
xml·java·前端·mybatis
不爱学英文的码字机器1 小时前
[JavaScript] 运算符详解
开发语言·javascript·ecmascript
Lysun0012 小时前
redux 结合 @reduxjs/toolkit 的使用
开发语言·前端·javascript·react·redux
Q825564992 小时前
‌无法运行CAD缺少依赖组件Microsoft Edge WebView2 Runtime‌,或您没有足够权限来运行 AutoCAD解决方案
前端·microsoft·edge
@前端小菜2 小时前
探秘JavaScript:手写memoize函数全解析
开发语言·javascript·ecmascript