五分钟带你深入了解 this

五分钟带你深入了解 this

为什么要有 this

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

this 用在哪

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

thisNode中指向{};在网页中输出,则指向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()  

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

隐式丢失(隐式绑定)

  • 当一个函数被赋值给变量独立调用 时,原本的隐式绑定会丢失,退化为默认绑定(指向 windowundefined)
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
相关推荐
粉末的沉淀7 小时前
vue:Vite项目中高效管理纯色SVG图标的方案
前端·javascript·vue.js
FlyWIHTSKY7 小时前
JavaScript 和 TypeScript 分别是什么,可以相互写吗
javascript·ubuntu·typescript
YHHLAI7 小时前
JavaScript 数据结构精讲:数组底层与实战避坑
开发语言·javascript·数据结构
moMo7 小时前
Promise 的本质:不是异步处理,而是流程控制
javascript
dotnet907 小时前
PDF 页面尺寸上限是 14400。iText 直接加载成功的大图可能超过这个限制,需要在 setPageSize 之前等比缩放。
前端·javascript·html
threelab7 小时前
Three.js 几何图形变换 | 三维可视化 / AI 提示词
开发语言·前端·javascript·人工智能·3d·着色器
云水一下7 小时前
TypeScript 从零基础到精通(七):从配置到全栈项目落地
前端·javascript·typescript
十九画生8 小时前
从同步到异步:重新理解 JavaScript 的执行机制
javascript
半个落月8 小时前
JavaScript 同步异步与 Promise 详解 —— 从 Event Loop 到手写 sleep
javascript
触底反弹8 小时前
深入理解 JavaScript 同步与异步:从 Event Loop 到 async/await
javascript