五分钟带你深入了解 this

五分钟带你深入了解 this

为什么要有 this

  • this是 js 中的一个关键字 ,它能做到隐式地传递一个对象的引用,可以让代码更高效、更简洁,易于复用。

this 用在哪

  • 有域的地方就可以用
  1. 全局 this === window

this在Node中指向{};在网页中输出,则指向window

我们在网页端输出this:

arduino 复制代码
console.log(this)
  1. 函数体内
javascript 复制代码
function foo(){
   var a = 0
   console.log(this.a)
}

块级作用域内this无意义,因为this的绑定只发生在函数调用和全局作用域中

this 用在不同的地方,代指的内容是不一样的

this的绑定规则

默认绑定

  • 当函数独立调用 时,函数中的 this指向window对象,如果console.log(this)会输出undefined

什么是独立调用:

scss 复制代码
function foo(){
    console.log(this)
}
foo()   

这里会输出 undefined,像这样声明一个函数,然后没用什么前缀来调用,就是独立调用

隐式绑定规则

  • 当一个函数被一个上下文对象所拥有,并被该对象调用,函数中的this指向该对象
javascript 复制代码
function foo(){
    console.log(this)
}
var obj = {
    a: 1,
    foo: foo      
}
obj.foo()  

调用点有. 或[],就是非独立调用

隐式丢失(隐式绑定)

  • 当一个函数被赋值给变量 后独立调用 时,原本的隐式绑定会丢失,退化为默认绑定(指向 window或undefined)
css 复制代码
function foo(){
    console.log(this.a)
}
var obj = {
    a: 1,
    foo: foo
}
var oo = {
    a: 2,
    foo: obj      
}
oo.foo.foo()     

oo.foo 指向 obj,不是foo

显式绑定

显式绑定有三种类型:

  1. fn.call(obj) 可以把函数的this强行绑定到obj中去,并执行

call的源代码会触发fn()

javascript 复制代码
function foo(x, y){
    console.log(this.a, x + y)   
}

var liu = { a: 1 }
foo.call(liu, 1, 2)             

会直接输出 1 3

  1. fn.apply(obj,[x,y])
css 复制代码
var jie = { a: 2 }
foo.apply(jie, [2, 3])           

输出 2 5

和call大部分一样,但apply接受参数方式不一样,要用数组传递

  1. var bar = fn.bind(obj,x,y) bar()
ini 复制代码
var fufu = { a: 3 }
const bar = foo.bind(fufu, 1, 4)  
bar()                                  

输出 3 5

也可以分步传参

scss 复制代码
const bar2 = foo.bind(fufu, 1)
bar2(4)                             

如果我多写一个参数

scss 复制代码
const bar2 = foo.bind(fufu, 1,4)
bar2(5)            

输出结果不变,因为会优先找 bind() 里的参数

bind执行后一定返回一个新参数,不会立刻执行

  1. new 绑定
  • new 的原理会导致函数的 this指向实例对象obj
csharp 复制代码
function Person(){
    this.name = 'jie'
}
const p = new Person()

让我们复习一下new的工作原理:

  1. 创建一个空对象 {}
  2. 让 this指向这个空对象
  3. 执行构造函数中的代码
  4. 让对象.__proro__==Person.prototype

你会发现,这和# 万物皆对象?带你梳理JS原型及其查找链机制讲的new的工作原理不太一样?这才是更细节的版本。

new 的原理会导致函数的 this 指向实例对象。

箭头函数

  • 箭头函数没有自己的this
  • 写在箭头函数内的 this是其外部非箭头函数的this
  • 箭头函数不能作为构造函数来使用,new的执行步骤中用到了把this指向其prototype

例如:

php 复制代码
function foo(){
    var fn = ()=>{
        this.a = 2

    }
    fn()
}
var obj ={
    a: 1,
    bar: foo
}
obj.bar()
console.log(obj);

输出{ a: 2, bar: [Function: foo] }

总结

1.看到this时候做两个判断:这个this是谁的,这个this代指的是谁

2.一图让你明白:

调用方式 绑定规则 this指向
foo() 默认绑定 window/ undefined
obj.foo() 隐式绑定 obj
foo.call(obj) 显式绑定 obj
new Person() new绑定 实例对象
()=>{} 箭头函数 外层函数的this
相关推荐
Hello.Reader14 分钟前
Three.js / Cesium 卡顿怎么办?把三维渲染搬到 GPU 服务器
服务器·开发语言·javascript
chi113015 分钟前
【无标题】
前端·javascript·python
萝卜兔00842 分钟前
PIKACHU_UnsafeFileUpload
javascript·php
程序员大阳13 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
香芋芋圆17 小时前
iD-editor 详解|OSM官方在线编辑器,基于D3.js的轻量地图编辑器
开发语言·javascript·编辑器
晗夜未央19 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
jktantan20 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我1234521 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳21 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck1 天前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts