thinkyou 发表于 2022-1-12 20:31

js的This指向

本帖最后由 thinkyou 于 2022-1-13 14:20 编辑

function foo() {
console.log(this.a)
}
var a = 1
foo()
const obj = {
a: 2,
foo: foo
}
obj.foo()
const c = new foo()


1.对于直接调foo来说,不管foo函数被放在了什么地方,this一定是window

2.对于obj.foo()来说,我们只需要记住,谁调用了函数,谁就是this ,所以在这个场景下foo函数中的 this 就是obj 对象

3.对于new 的方式来说,this被永远绑定在了c上面,不会被任何方式改变this

我们再来看看箭头函数的this

function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())

1.首先箭头函数其实是没有this 的,箭头函数中的this 只取决包裹箭头函数的第一个
普通函数的this 。在这个例子中,因为包裹箭头函数的第一个普通函数是a ,所以此
时的this 是window 。另外对箭头函数使用bind 这类函数是无效的

2.最后种情况也就是bind 这些改变上下文的API 了,对于这些函数来说, this 取决
于第一个参数,如果第一个参数为空,那么就是 window 。

3.那么说到bind ,不知道大家是否考虑过,如果对一个函数进行多次bind ,那么上下文
会是什么呢?

let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)() // => ?

如果你认为输出结果是a ,那么你就错了,其实我们可以把上述代码转换成
另一种形式

// fn.bind().bind(a) 等于
let fn2 = function fn1() {
return function() {
return fn.apply()
}.apply(a)
}
fn2()

可以从上述代码中发现,不管我们给函数bind 几次, fn中的this 永
远由第一次bind 决定,所以结果永远是 window

let a = { name: 'poetries' }
function foo() {
console.log(this.name)
}
foo.bind(a)() // => 'poetries'

以上就是 this 的规则了,但是可能会发生多个规则同时出现的情况,这时
候不同的规则之间会根据优先级最高的来决定 this 最终指向哪里。

首先, new 的方式优先级最高,接下来是 bind 这些函数,然后是obj.foo() 这种调用方式,最后是 foo 这种调用方式,同时,箭头函数的
this 一旦被绑定,就不会再被任何方式所改变。
总结:
(1)普通函数调用: 函数名()         ->this指向window


(2)对象方法调用: 对象名.方法名()   ->this指向对象


(3)构造函数调用: new 函数名()      ->this指向new创建的实例对象

上下文调用方式:
1.call上下文调
function fn(a,b){
            console.log( this )
            console.log(a+b)
      }
      fn(1,2)//this指向window
      //函数名.call(修改的this,参数1,参数2,....)
      fn.call({name:'张三'},10,20)

2.apply上下文调用                //场景1:伪数组转成真数组


function fn(a,b){
            console.log(this)
            console.log(a+b)
      }
//函数名.apply(修改的this, 数组/伪数组 )
      //apply传参的时候会自动的遍历这个数组,然后按照循序逐一传参a = b=
fn.apply({name:'李四'},)

3.bind上下文调用


//bind不会立即调用函数,而是得到一个修改this之后的新函数
function fn(a,b){
            console.log(this)
            console.log(a+b)
      }
let newFn = fn.bind({name:'王五'}) //这里如果传实参后,下面传参就无效了
      newFn(25,66)







请说说call apply bind的区别及对应应用场景(面试必问点)

共同点:
都可以修改this的指向


call、apply的区别:接受参数的方式不一样。
bind:不立即执行。而apply、call 立即执行。


call逗号分隔逐一传递实参
apply 必须是一个包含多个参数的数组(或类数组对象)
bind不会立即执行,会返回修改this后的一个函数



bhbhxy 发表于 2022-1-13 08:00

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

因为匿名函数的this指向总是window,除了使用that,还可以使用箭头函数

Yo丨Se7ven 发表于 2022-1-13 10:12

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

在vue中实际开发异步请求一般都用箭头函数调用

easy909 发表于 2022-1-12 21:43

窝草,这是技术论坛么

无缺i 发表于 2022-1-12 22:04

vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因为啥吗

thinkyou 发表于 2022-1-12 22:26

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

还没学到哪里不过快了,马上学node.js了:lol

伸手党党魁 发表于 2022-1-13 08:56

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

你试试回调别用function,而是直接上箭头函数

jinzhu160 发表于 2022-1-13 08:57

MmMDou 发表于 2022-1-13 09:18

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

你的异步请求用箭头函数

rxxcy 发表于 2022-1-13 09:33

this能不能写小写 很难受--

我今天是大佬 发表于 2022-1-13 09:54

无缺i 发表于 2022-1-12 22:04
vue异步发送请求的时候 使用this指向data数据不行,必须要 let that = this, 然后用that指向,大佬知道是因 ...

使用匿名函数解决
页: [1] 2
查看完整版本: js的This指向