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

相关推荐
菜鸟一枚在这30 分钟前
深入解析设计模式之单例模式
开发语言·javascript·单例模式
CL_IN41 分钟前
企业数据集成:实现高效调拨出库自动化
java·前端·自动化
浪九天2 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ3 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
C#Thread3 小时前
C#上位机--流程控制(IF语句)
开发语言·javascript·ecmascript
椰果uu3 小时前
前端八股万文总结——JS+ES6
前端·javascript·es6
微wx笑3 小时前
chrome扩展程序如何实现国际化
前端·chrome
~废弃回忆 �༄3 小时前
CSS中伪类选择器
前端·javascript·css·css中伪类选择器
CUIYD_19893 小时前
Chrome 浏览器(版本号49之后)‌解决跨域问题
前端·chrome
IT、木易3 小时前
跟着AI学vue第五章
前端·javascript·vue.js