五分钟带你深入了解 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
相关推荐
天若有情67327 分钟前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具
林语琛1 小时前
我写的 switch…break 被 Babel 偷偷吞了
前端·javascript·babel
liuchangng2 小时前
Jev 模型研究:从生成式大模型到决策式模型——System One、RLCD 校准与采用边界
java·javascript·人工智能·python·深度学习
我命由我123453 小时前
CSS - CSS 媒体查询 orientation
前端·javascript·css·html·css3·html5·js
志尊宝6 小时前
Vue3 零基础每日笔记(048):嵌套路由与命名视图——后台管理系统布局雏形
前端·javascript·vue.js·笔记·html5
@tangguo1236 小时前
npm 和 yarn 配置说明
前端·javascript·npm·node.js·yarn
志尊宝7 小时前
Vue3 零基础每日笔记(052):路由常见坑一次排雷——404、刷新丢参数、部署白屏
前端·javascript·vue.js·笔记·html5
linux_cfan7 小时前
videojs v10 源代码系列解读:13 · 能力型媒体契约:`Media` 的组合接口
前端·javascript·音视频
福兮说7 小时前
Canvas 文字排版:measureText 量出来的宽度为什么总是不对
前端·javascript
用户80806181436938 小时前
JavaScript 面向对象入门到精通
前端·javascript